Im having problems with something,
Im not sure if its my understanding of pointers, or Unreal itself. Here is my code
TArray<Anode> nodes;
TActorIterator<Anode> ActorItr = TActorIterator< Anode >(GetWorld());
while (ActorItr) //Go through EVERY Node and check distance
{
if (this->GetUniqueID() != ActorItr->GetUniqueID())
{
//Check Distance
if (FVector::DistSquared(this->GetActorLocation(), ActorItr->GetActorLocation()) < 262144) //Check the distance between the two nodes.
{
Anode node = ActorItr;
//Anode* node = Cast<Anode>(*ActorItr);
nodes.Add(node); //Calls a error because
//cannot convert from 'TActorIterator<Anode>' to 'Anode'
}
}
}
}
So my issue is i cannot convert the Actor Iterator to my TArray, and i have played around with de-referencing etc, i got it to compile but crash at run-time. Thanks!
Edit: For clarity
i have tried
Anode node = *ActorItr;
but got a error C2440: 'initializing' : cannot convert from 'Anode *' to 'Anode'.
I then tried
Anode *node = *ActorItr;
nodes.Add(*node);
It compiled but created a run time error with unhanded memory or something, i think this is because its just handing the pointer to the TArray without handling the issue (is that right?). I understand the concept i feel, but not the syntax.
The actor iterator is not an actor, so direct assignment doesn't make any sense. Try dereferencing the iterator (Anode* node = *ActorItr;), that operator should be overloaded to return the current element of the iteration, i.e. the node you want to use.
Related
My code is as so...
ArrayList<Ray> rays = new ArrayList<Ray>();
Particle() {
for(int a=0; a < 360; a+=10) {
append(rays, new Ray(position, radians(a)));
}
}
I'm initializing an ArrayList of the class Ray. Then I run through a for loop and am attempting to
append a new Ray() to the list. I get no errors in the editor but whenever I run the code I get the error message: IllegalArgumentException: Argument is not an array
I've looked around and nothing seems to answer my question. Why is this happening?
The append function is for use with arrays (e.g.: rays[]). However rays is an ArrayList. Hence, you need to use the add method:
append(rays, new Ray(position, radians(a)));
rays.add(new Ray(position, radians(a));
I'm having some trouble and my brain hurts by reading those "pointers" - how do you efficiently read the pointers and visualizing the pointers?
Here is a simple example below yet daunting task in my brain to read/track of those pointers (previous and next). How do we approach this with less cognitive effort?
How do I see/visualize the removing of node in the linked list is thinking the linked list like a line of people and people pointing (hellish rebuke in dnd 5e) each other if they are previous and next to the person... That helps but not efficiently.
public func remove(node : Node<Element>) -> Element {
let prev = node.previous
let next = node.next
if let prev = prev {
prev.next = next
}
else {
head = next
}
if let next = next {
next.previous = prev
}
else {
tail = prev
}
node.previous = nil
node.next = nil
return node.value
}
Draw each node as a box.
In each box, provide a section "pointer". Draw an arrow from the pointer section to another box.
Think of pointers as mailing addresses. Each box (node) has the (mailing) address of the previous and next nodes.
If you remove one node, you have to update the mailing addresses stored in the neighboring nodes so they no longer try top point to the now-missing node.
It is not a big jump from mailing address to memory address, which is what pointers actually store.
First: Thanks for reading this question and tryin' to help me out. I'm new to the whole threading topic and I'm facing a serious mutex deadlock bug right now.
Short introduction:
I wrote a game engine a few months ago, which works perfectly and is being used in games already. This engine is based on SDL2. I wanted to improve my code by making it thread safe, which would be very useful to increase performance or to play around with some other theoretical concepts.
The problem:
The game uses internal game stages to display different states of a game, like displaying the menu, or displaying other parts of the game. When entering the "Asteroid Game"-stage I recieve an exception, which is thrown by the std::lock_guard constructor call.
The problem in detail:
When entering the "Asteroid Game"-stage a modelGetDirection() function is being called to recieve a direction vector of a model. This function uses a lock_guard to make this function being thread safe. When debugging this code section this is where the exception is thrown. The program would enter this lock_guard constructor and would throw an exception. The odd thing is, that this function is NEVER being called before. This is the first time this function is being called and every test run would crash right here!
this is where the debugger would stop in threadx:
inline int _Mtx_lockX(_Mtx_t _Mtx)
{ // throw exception on failure
return (_Check_C_return(_Mtx_lock(_Mtx)));
}
And here are the actual code snippets which I think are important:
mutex struct:
struct LEMutexModel
{
// of course there are more mutexes inside here
mutex modelGetDirection;
};
engine class:
typedef class LEMoon
{
private:
LEMutexModel mtxModel;
// other mutexes, attributes, methods and so on
public:
glm::vec2 modelGetDirection(uint32_t, uint32_t);
// other methods
} *LEMoonInstance;
modelGetDirection() (engine)function definition:
glm::vec2 LEMoon::modelGetDirection(uint32_t id, uint32_t idDirection)
{
lock_guard<mutex> lockA(this->mtxModel.modelGetDirection);
glm::vec2 direction = {0.0f, 0.0f};
LEModel * pElem = this->modelGet(id);
if(pElem == nullptr)
{pElem = this->modelGetFromBuffer(id);}
if(pElem != nullptr)
{direction = pElem->pModel->mdlGetDirection(idDirection);}
else
{
#ifdef LE_DEBUG
char * pErrorString = new char[256 + 1];
sprintf(pErrorString, "LEMoon::modelGetDirection(%u)\n\n", id);
this->printErrorDialog(LE_MDL_NOEXIST, pErrorString);
delete [] pErrorString;
#endif
}
return direction;
}
this is the game function that uses the modelGetDirection method! This function would control a space ship:
void Game::level1ControlShip(void * pointer, bool controlAble)
{
Parameter param = (Parameter) pointer;
static glm::vec2 currentSpeedLeft = {0.0f, 0.0f};
glm::vec2 speedLeft = param->engine->modelGetDirection(MODEL_VERA, LEFT);
static const double INCREASE_SPEED_LEFT = (1.0f / VERA_INCREASE_LEFT) * speedLeft.x * (-1.0f);
// ... more code, I think that's not important
}
So as mentioned before: When entering the level1ControlShip() function, the programm will enter the modelGetDirection() function. When entering the modelGetDirection() function an exception will be thrown when tryin' to call:
lock_guard<mutex> lockA(this->mtxModel.modelGetDirection);
And as mentioned, this is the first call of this function in the whole application run!
So why is that? I appreciate any help here! The whole engine (not the game) is an open source project and can be found on gitHub in case I forgot some important code snippets (sorry! in that case):
GitHub: Lynar Moon Engine
Thanks for your help!
Greetings,
Patrick
GameObject[] rm = FindObjectsOfTypeAll(typeof(RoadMovement)) as GameObject[];
if (Input.GetKeyDown (KeyCode.LeftArrow))
{
foreach(GameObject r in rm) //objectRefrence not set to instance of an object error here
{
var bounds1 = r.renderer.bounds;
var bounds2 = player.renderer.bounds;
Transform roadtransform = r.transform;
if(bounds1.Intersects(bounds2))
{
if (this.transform.position.x > r.renderer.bounds.min.x)
this.transform.position = new Vector3 (this.transform.position.x - 0.6f, this.transform.position.y, this.transform.position.z);
}
}
}
What is difference between FindObjectOfType and FindObjectOfTypeAll? I want to get all the objects that have RoadMovement script attached to them.I understand the error: Object reference not set to an instance but not sure how to fix this?
First problem: FindObjectsOfTypeAll has been deprecated for quite some time, and is no longer documented at all in current versions of Unity. Because you're comparing objects in the scene, it looks like you want Object.FindObjectsOfType.
Second problem: the lookup call you're making doesn't return an array of GameObjects, so the as operator will return null when the cast fails. You mentioned that RoadMovement is a behavior script you wrote. That implies that every RoadMovement has a GameObject, but not that every RoadMovement is a GameObject.
This is also why you're getting an InvalidCastException that you're asking about. Understand your return types and you will understand the error.
Recent Unity versions even added a generic version of FindObjectsOfType:
RoadMovement[] roadMovements = Object.FindObjectsOfType<RoadMovement>();
foreach (RoadMovement roadMovement in roadMovements) {
GameObject myGameObject = roadMovement.gameObject;
//do something
}
In the game I'm working on I would like to give users the possibility to select between asynchronous and real-time turn-based matches. The one thing I'm missing from the latter is how do I know who's got the first turn. I'm trying to find a way to detect who's got connected first and set that player's turn automatically. Unfortunately, it seems that both players get connected at the same time since right after finding a match expectedPlayersCount yields 1 for both players and in the didChangeState event that same variable yields 0 for both of them too. So I have no way to tell who's got first to the match since it seems that it all happens simultaneously.
As a temporary fix, I'm just using their IDs. The one with the lowest ID is the one having the first turn. However, I'm trying to find a better way since with this approach player A will always get the first turn when playing against player B and that represents a small advantage in my game.
This method is what I call when starting a new game. I pass a realTime bool value to specify whether the game returned by the game center wrapper should be a GKMatch or GKTurnBasedMatch.
//Calculate the level group to find other players in the same group
NSInteger levelGroup = (self.player.levelValue / STLevelSkillInterval) * STLevelSkillInterval;
//Find a match for the local player
[self.gameCenter findMatchWithPlayerAttributes:levelGroup realTime:realTime group:0 onCompletion:^(GKTurnBasedMatch *turnMatch, GKMatch *realTimeMatch) {
[self handleTurnMatchFound:turnMatch realTimeMatch:realTimeMatch completionBlock:onCompletion];
}];
...
This method here is the responsible to handle game center response after finding match. The create and synchronize method stores a match instance in CoreData and also fills its data by fetching the corresponding info from Game Center and my backend. So if at the time of that's done the expected player count reached 0, I call the completion block immediately since the match can begin. Otherwise I just store the completion block so I can use it later when the other player connects to the match. The problem in that part is that it never reaches 0, not for any of the two players.
- (void)handleTurnMatchFound:(GKTurnBasedMatch *)turnMatch realTimeMatch:(GKMatch *)realTimeMatch completionBlock:(void(^)(STMatch *match, NSError *error))onCompletion
{
if (turnMatch != nil)
{
[self createAndSynchronizeLocalMatch:turnMatch onCompletion:^(STMatch *localMatch) {
onCompletion(localMatch, nil);
}];
}
else if (realTimeMatch != nil)
{
[self createAndSynchronizeRealTimeLocalMatch:realTimeMatch onCompletion:^(STMatch *localMatch) {
if (realTimeMatch.expectedPlayerCount == 0)
{
onCompletion(localMatch, nil);
}
else
{
self.findRealTimeMatchCompletionBlock = onCompletion;
}
}];
}
else
{
onCompletion(nil, nil);
}
}
...
This is the method that handles player's state changes. So basically here I just update the local instance of the real time match with values from the connected player and then I call the completion block stored earlier.
- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state
{
if (state == GKPlayerStateConnected)
{
STMatchParticipant *placeholderParticipant = [self.realTimeMatch getMatchParticipantWithPlayerId:nil];
placeholderParticipant.playerId = playerID;
placeholderParticipant.statusValue = GKTurnBasedParticipantStatusActive;
//This will sync the information for the connected player only
[self syncAllPlayerInfoForRealTimeMatchOnCompletion:^(NSArray *players) {
self.findRealTimeMatchCompletionBlock(self.realTimeMatch, nil);
}];
}
else
{
//Notify the observers that the participant has disconnected from the match
STMatchParticipant *participant = [self.realTimeMatch getMatchParticipantWithPlayerId:playerID];
for (id<STTurnBasedMatchDelegate> observer in self.matchesObservers)
{
if ([observer respondsToSelector:#selector(realTimeMatch:participantDidDisconnect:)])
{
[observer realTimeMatch:self.realTimeMatch participantDidDisconnect:participant];
}
}
}
}
I would appreciate any comments.
Instead of trying to determine who got connected first, why don't you just have all the players pick a random number using arc4random ?
int randomNumber = arc4random%1000000;
The player with the biggest number can play first. You will have to make sure all the players send each other their random numbers so everyone can compare and decide who is first.
In the above example, the range would be upto 1 million, so the odds of two players picking the same random number is low.
If two players do pick the same random number, you could compute the hash of their playerId's, and have the player with the larger hash be first.
if ([GKLocalPlayer localPlayer].playerID.hash > otherPlayerId.hash )
The chances of a hash collision occurring are very low, since the playerId strings are short. You can still check for this collision and handle it appropriately (maybe by hashing again ;) ).