Jump to content

  • Log In with Google      Sign In   
  • Create Account

Khatharr

Member Since 24 Apr 2010
Offline Last Active Private

#5265528 How To Check If Grounded In 2D Unity Game?

Posted by on 08 December 2015 - 08:18 PM

Yeah. I was using a sensor before, but I'm checking out the contact normal method that Happy was talking about.




#5265525 How To Check If Grounded In 2D Unity Game?

Posted by on 08 December 2015 - 08:07 PM

What method do you use for leaving the grounded state with that method? I'm catching groundedness in OnCollisionStay() and setting grounded to false at the end of FixedUpdate(), but there's some noticeable latency when landing. I considered using OnCollisionEnter() and OnCollisionExit(), but the exit could potentially incorrectly set grounded to false when walking between colliders horizontally.




#5265360 How To Check If Grounded In 2D Unity Game?

Posted by on 07 December 2015 - 06:20 PM

 

 

Unity provides a very simple way to do this - override OnCollisionStay2D(), check if the collider is a ground object, and use that to update some boolean isGrounded flag in your class.

 
In order to do it that way you'd need to have ground colliders only on the tops of ground objects. Otherwise you'd be able to jump off the sides or bottom of things that are marked as ground.

 


You could just check the contacts in the Collision2D object. If one has a normal that is pointing up, then you are touching ground.
 
// a max slope of 30 degrees
private static float GroundAngleTolerance = Mathf.Cos(30.0f * Mathf.Deg2Rad);

void OnCollisionEnter2D(Collision2D coll) 
{
  foreach(ContactPoint2D contact in coll.contacts)
  {
    if (Vector3.Dot(contact.normal, Vector3.up) > GroundAngleTolerance)
    {
      // this collider is touching "ground"
    }
  }
}
EDIT: I quoted ground because this would consider any contact that touches the bottom of the player as ground

 

 

Nice. I think I'll try that out.




#5265177 How To Check If Grounded In 2D Unity Game?

Posted by on 06 December 2015 - 03:27 PM

Unity provides a very simple way to do this - override OnCollisionStay2D(), check if the collider is a ground object, and use that to update some boolean isGrounded flag in your class.

 

In order to do it that way you'd need to have ground colliders only on the tops of ground objects. Otherwise you'd be able to jump off the sides or bottom of things that are marked as ground.




#5264986 Finding the angle between two vectors on x axis

Posted by on 05 December 2015 - 01:34 AM

From what you're describing it sounds like you're basically implementing a lookAt.

 

Take a look toward the bottom of this page to see how such a matrix may be constructed:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb204936%28v=vs.85%29.aspx

 

Edit:

The chirality of this was bothering me, so I made a test to check it out. It's left-handed, but invert the "eye" and "at" vectors when calculating the new z axis vector. This was the function I ended up with (in Unity, but the math is the relevant part):

    Matrix4x4 makeMatrix(Vector3 position, Vector3 target)
    {
        Vector3 z = (position - target).normalized;
        Vector3 x = Vector3.Cross(Vector3.up, z).normalized;
        Vector3 y = Vector3.Cross(z, x);

        Matrix4x4 mat = Matrix4x4.identity;
        mat[0, 0] = x.x;    mat[0, 1] = y.x;    mat[0, 2] = z.x;
        mat[1, 0] = x.y;    mat[1, 1] = y.y;    mat[1, 2] = z.y;
        mat[2, 0] = x.z;    mat[2, 1] = y.z;    mat[2, 2] = z.z;
        mat[3, 0] = -Vector3.Dot(x, position);
        mat[3, 1] = -Vector3.Dot(y, position);
        mat[3, 2] = -Vector3.Dot(z, position);

        return mat;
    }



#5264905 Simple 2D collision detection for a platform game (easiest solution possible...

Posted by on 04 December 2015 - 02:22 PM

A spatial hash is effective as a broad phase.

 

http://www.gamedev.net/page/resources/_/technical/game-programming/spatial-hashing-r2697

 

This doesn't solve your clipping problem though. This is to manage collision performance, since you expressed concerns about that.




#5264825 Why didn't somebody tell me?

Posted by on 03 December 2015 - 08:44 PM

Dragging items or selections in an explorer window? Hold a mod key to get more actions. CTRL will give you copy I believe, while SHIFT will give you move (may be switched, but for sure gives those options).

Did you know you can drag with the right mouse button and it will open a context menu with options when you drop?




#5264795 Simple 2D collision detection for a platform game (easiest solution possible...

Posted by on 03 December 2015 - 03:35 PM

A broad phase test is a cheap collision test or method of organization that discards obvious misses before running more expensive tests. You expressed concern about performance costs related to continuous detection (the storing the previous position thing). Incidentally, rather than having some external buffer somewhere, you could just hold the previous position in the object itself. If your stages are very large at all then you'll probably want some kind of broad phase in any case.

 

Fortunately in 2D tile-based games you can implement broad phase tests quite easily.

 

http://www.wildbunny.co.uk/blog/2011/12/14/how-to-make-a-2d-platform-game-part-2-collision-detection/

 

You just create a rect that encloses the entity at its previous and current positions, then you only have to test against tiles that intersect that rect.




#5264787 Simple 2D collision detection for a platform game (easiest solution possible...

Posted by on 03 December 2015 - 02:55 PM

If it is the bullet through paper problem then you could try not using paper, but the best solution is continuous detection. Are you using any kind of broad-phase test?




#5264622 Simple 2D collision detection for a platform game (easiest solution possible...

Posted by on 02 December 2015 - 01:40 PM

When you test for collision, don't resolve in the testing phase. Generate a list of contacts for any collider that can respond to collisions (iow - not walls).

 

When an object intersects both the left wall and the floor, it should have two contacts in its list (assuming it hit nothing else). Once you've generated a list of contacts for everything you move through that list and resolve the situation, considering all the contacts together instead of trying to resolve them separately, which could result in missed responses. It also allows dynamic objects to bounce off one another accurately, since both of the objects register the contact before either of them try to resolve it.

 

A "contact" is just a struct that contains all of the relevant information about the collision, such as penetration and the surface normal of what was hit, etc.

 

Make sense?

 

 




#5264616 Simple 2D collision detection for a platform game (easiest solution possible...

Posted by on 02 December 2015 - 01:21 PM

Okay, but are you generating contact lists?




#5264516 Simple 2D collision detection for a platform game (easiest solution possible...

Posted by on 01 December 2015 - 06:54 PM

I'm not sure about your higher level strategy from this. Are you generating a list of contacts? It sounds like you may be in a situation where contact resolution for one object is overriding resolution for other objects.

 

It may just be a fencepost error though. You're doing:

 

if (penetration.Y < penetration.X) { /*some things happen*/ }

else if (penetration.X < penetration.Y) { /*some other things happen*/ }

 

Which has an obvious excluded case...




#5264497 handling data/state in a board game - composition/coupling

Posted by on 01 December 2015 - 05:38 PM

The reasoning that people use to discourage public data members in classes is that they may invalidate the class invariants and that they may make it harder to refactor if you decide to change the way the class works.

 
I guess another reason people advise against public variables because it will be harder to track bugs, because there are more access points to the data. While this is true, in this case the game logic & data will be all contained in GameEngine and I can restrict access to that from the rest of the game code, so bugs in the logic shouldn't be too hard to track IMO.

 
More that it's harder to create bugs in the first place. You gave the example of not letting a player have negative money. That could be made an invariant for the player class, in which case the variable holding player's money should definitely be private, and functions that change the amount of money should observe the limits and somehow indicate a problem if you try to remove too much.


#5264485 handling data/state in a board game - composition/coupling

Posted by on 01 December 2015 - 04:23 PM

Thanks for your post, it was very helpful. Always good to see how other people approach a problem.
 

In this way the functions within the scene can access the persistent state by something like:
 
game->statePackage->board.freeParkingMoney;

 
Ah, so in this case, board and freeParkingMoney would be public members? To me that seems fine, though I keep reading how having public variables / getters in a class would be bad design.

 


Firstly, not everything needs to be a class. You can use structs for composition. (And nobody will argue against it... Hopefully...)
 
Frankly though, if you disallow public state and getters like some people suggest (stares pointedly at Herb and Bjarne) then you're just making your life far more difficult without an equally valuable payoff.

 

The reasoning that people use to discourage public data members in classes is that they may invalidate the class invariants and that they may make it harder to refactor if you decide to change the way the class works.

 

In the first case, learn what invariants are and why they're important and then don't invalidate your invariants through public members. If you understand invariants then it's common sense, and the rule about public member data is really erring too far on the side of caution in my opinion.

 

In the second case, modern IDEs will let you chase down references to a member variable, so it's really not hard to change at all.

 

There's an additional argument if you're writing an interface or something similar, but in that case you should just use trivial getters/setters. You're not writing an interface here, so it's not really relevant. The concern in that case is that you'd be violating the open/closed rule (open for extension / closed for modification), which means that the people using your interface may write code that uses the public members, then if you changed them to be member functions (getters/setters with some logic) instead your clients may have to re-write a bunch of their code.
 

Anyway, it seems perfectly fine for me to allow GameData to publically access its sub-objects, and their sub-objects, or indeed any data contained within it, directly. Though it definitely seems to be frowned upon. It would just be so much easier. I mean, the whole buyDeed function could be written like:

void buyDeed(ID deedID, GameData gameData) {
    auto &activePlayer = gameData.players.find(gameData.activePlayer);
    auto &playerDeeds = activePlayer.ownedDeeds;
    auto &bankDeeds = gameData.board.bank.ownedDeeds;
    auto &deedToMove = bankDeeds.find(deedID);
    auto &playerMoney = activePlayer.money;
    
    if ( playerMoney > deedToMove.cost() ) {
	transferDeed(deedID, playerDeeds, bankDeeds);
	playerMoney -= deedToMove.cost();
    }
}
I can only imagine what a mess that would be using best-practices and private data, if each sub-object could only access its own data. I'd need to write a load of member functions in each sub-class and pass through them all. And I'd need to pass as a parameter the required data so the function at the bottom has it. TBH there'd be a load of getters/setters anyway, so the members may aswell be all public. They are all sub-objects related to the root class of GameData anyway, it's not like i'm exposing them to the rest of the game code.
 
What does everyone else think?

 

 
That's a little overboard with the references there. The idea I was communicating about references is that you can use them to avoid having to type out the full chain for some variable that you use several times in the same function. In the case shown you're just creating a reference for everything, which is actually more typing rather than less, lol.

void buyDeed(ID deedID, GameData gameData) {
    auto &activePlayer = gameData.players.find(gameData.activePlayer);
    auto &bankDeeds = gameData.board.bank.ownedDeeds;
    
    if ( playerMoney > deedToMove.cost() ) {
	transferDeed(deedID, activePlayer.ownedDeeds, bankDeeds);
	activePlayer.money -= bankDeeds.find(deedID).cost();
    }
}

 Anyway, these classes/structs are intended to store state for access by the program. The program has to be able to access that state in some way or else they fail their job.




#5264389 How Do You Do 2D Movement In Unity?

Posted by on 01 December 2015 - 05:00 AM

https://www.youtube.com/playlist?list=PLFt_AvWsXl0f0hqURlhyIoAabKPgRsqjz

 

He's making something complex. Hence the complexity.

 

If you just want basic platform mechanics then the Unity tutorials can get you started:

 

https://unity3d.com/learn/tutorials/modules/beginner/2d/2d-controllers?playlist=17093

 

Mario-esque controls require a more specialized implementation, and that's a more general problem than just Unity.

 

Attached is an example project with some more refined controls.

Attached Files






PARTNERS