Unity C# collision detection - unity3d

I made/trying to make a melee two-dimensional game in Unity. The enemy can attack the player no problem, but the other way around is very finicky and unreliable. The enemy has both a ridged body and a box collider, and the same with the player.
This code is all on the enemy
code: https://pastebin.pl/view/a6d99e0d

Because I do not know the specific project, I can not give a specific answer.
But I can provide a similar dilemma I have encountered before. My input was not responded in time in the game. When the player pressed after the jump key, the protagonist may not have been be able to jump in time. When I changed the FixedUpdate in the code to Update, the problem was solved.
Of course, my approach is flawed, but I hope my problem can be addressed to the subject. Bring some tips and good luck!

You're validating input, and updating physics both in the void OnTriggerEnter method. Physics updates much differently than the regular old Update() method does.
Your physics checks are already completed (I guess in this case it could be either or).
By calling Input.GetButtonDown() in this method, it has to grab the exact frame that button mashed down to return true.
The problem is, physics don't Update in the same way. Actually, you aren't even running a physics check this frame. That button just got completely ignored. Dang.
You have to come up with a better way to structure your code to process that input. Find a way that allows you check if the player is attacking, without relying on input. You could always try a state pattern.
See also MonoBehaviour.FixedUpdate().

Related

Recommended strategy for overriding certain Rigidbody collisions in Unity?

I'm looking for a little newbie advice on gamedev strategy and/or approach. I'm working on a game that uses Rigidbody physics in Unity and I've got a character interacting nicely with physical objects in the game world. The thing I'm trying to work through is that there are certain physical interactions that I want to control, but my own attempts to control them are conflicting with what Unity is already (correctly) doing.
For simplicity, let's just say I've got a Rigidbody-based player, and when certain Rigidbody-based objects collide with that player, I want to override where they deflect to. When I detect the collision and apply my own force with rb.AddForce(myForceVector, ForceMode.VelocityChange), Unity is also applying it's own force as a result of the same collision. I also tried setting the velocity directly with rb.velocity = myForceVector, which mostly works, but there are still situations where Unity applies force after I set the velocity so it's glitchy at best.
Other options I've considered are:
Use an additional, larger IsTrigger collision mesh to detect and handler the special type of collision I'm looking for before the actual collision occurs. That might work for slower speed projectiles, but likely will have the same issue for faster collisions.
Change the player to not being Rigidbody-based, which might work, but would require me to code a lot of the other interactions that are already working out of the box with Rigidbody physics.
Use RayCasting to detect when these special collisions might occur next and handle them before the actual collision. This is where I'm leaning currently.
Anyone have a recommended best practice for this kind of thing?
Thanks in advance!
The easiest way might just be to take full control. On the correctly timed press, disable the RigidBody and the Collider. Then just move it yourself to the target location. It's really hard to get precise control over a RigidBody -- every FixedUpdate(), it might be picking up force from collisions, and there can be many FixedUpdate() calls between Update() calls.
You could write a pretty simple coroutine using a Lerp() or Slerp() between the object's current and target position. That way, you could fully control how the object moves toward its target.
Just to follow up... I attempted to "take full control" as suggested in Alex M's answer above, but that ended up making a number of other things complicated in my specific situation. However, his comments about disabling the collider in the original question led me down a different path that ended up working well...
I ended up disabling the collider for the deflecting rigidbody upon impact and setting the velocity of the deflected body directly. That way, I was able to avoiding any additional force(s) applied from Unity while the collision was active. Once the deflected object was on it's way, I just had to reenable the collider.
Thanks, Alex!

Mouse cursor becomes locked during keyboard input

I'm attempting my first shot at using Unity. This is my first foray into game development and 3D environments. I'm following the tutorial for the survival shooter located here: https://unity3d.com/learn/tutorials/projects/survival-shooter/player-character?playlist=17144
I went to try mouse movement, which should change the direction of the player object, but found that the player does not change direction.
I have even tried copying the tutorial author's code directly, using it in its entirety and overwriting my original script. Their code can be found in the link.
Adding Debug.Log("Raycast not hitting"); to an else block in the Turning function causes the debug message to fire during each FixedUpdate, regardless of whether the mouse has been positioned over the floor.
Since you directly copied all scripts, I'm assuming that their are no issues with your scripts. This means that this issue is most likely located somewhere in your scene. The boolean controlling player, Physics.Raycast(camRay, out floorHit, camRayLength, floorMask). The else statement you used assures you that this function is returning false. I think the most likely reason this may be is that you do not have an object in the scene that has its layer set to floor. The aforementioned function will automatically return false if the RayCast does not find an object with a layer of floor within a range of camRayLengthunits. So, find or create an object that covers the entirety of the floor and set its layer to floor. I would also recommend looking at the scripting API documentation for Physics.Raycast so that you can better understand whats going on in the code. Here's a link to Unity's documentation: https://docs.unity3d.com/ScriptReference/Physics.Raycast.html

Unity not working collider in race game lap logic

I am making a racing game and I have created points 'round the map that you must pass in order to finish a lap.
Sadly, when the player passes the first part it doesn't indicate it and so it can't pass through the other one.
I am using OnCollisionEnter() but IsTrigger is activated on those points so that they have no collision.
I even added Debug.Log(""); to check if it actually does something but it wont show anything in the console. Here is the collision code in the car:
function OnCollisionEnter(col: Collision) {
... never gets to here
}
Note: Don't tell me to switch to C# because JavaScript(UnityScript) is being remove, I am well aware of that.
I believe your basic problem is you should be using
void OnTriggerEnter
instead of the OnCollision calls.
It is a situation where this annoying thing...
http://docs.unity3d.com/Manual/CollidersOverview.html
will solve your problem. Scroll down to:
"Collision action matrix"
You have to familiarize yourself with that, to use Unity. It's a pain.
To get an answer on SO, for specific cases of this type of problem, you need to provide the answers these eight questions:
on the "CAR"
rigidbody? / kinematic on or off? / collider ? / trigger on or off?
on the "WALL"
rigidbody? / kinematic on or off? / collider ? / trigger on or off?

Determine on which collider the collision has taken place

I have a gameobject with two sphere colliders attached. One has IsTrigger checked and the other not.
I want to execute different set of statements when collision occurs with different colliders. For example I want to play different sound for both different collisions. Is there any way to achieve it?
I tried OnTriggerEnter() but unfortunately it is called for both type of collisions since other colliding objects have triggered colliders. I just thought if we could somehow find out on which collider of the gameobject the collision has taken place we will be able to achieve it.
So is there any way to get through with this?
I have been using Unity for years and faced tons of problems like this, related to bad software design. I hope Unity guys will handle physics more carefully in future releases.
In the mean time, you can use Physics.OverlapSphere and Physics.CheckSphere to manually check if there is something that collides with your object. Remove the collider that you are using as a trigger and use these methods instead of OnTriggerEnter. This is a bit hacky, but this will do the job I think.
Make your colliders visible in the inspector (make them public or add [SerializeField] before it) and then tie in the colliders to the code that way.
Then, in your collisions, compare the colliding objects against your variables that are holding the colliders for you to keep them separate.
To detect for source trigger in OnTriggerEnter, you must use workaround with multiple gameobject hosting trigger and satellite scripts.
Allow me to link to my answer on gamedev SO:
https://gamedev.stackexchange.com/a/185095/54452

Unity Sprites - Collider not working Properly

I was following a tutorial on how to create a simple game called pong. As I was working on it. I stumbled on a bug that when the ball is to fast it will it passes through the paddle without colliding with the collider
As you can see in the screenshot
Is this some kind of a bug in unity? I need to get rid of this and don't want to have this in my game.
by the way this was the tutorial I was following . Brackeys
What do you mean by 'bypass the player control'? Do you mean it passes through the paddle without colliding with the collider, even though it should? Or does it get stuck? The screenshot makes it difficult to tell.
Either way, the first thing you're going to want to try is changing the collision detection setting of your Rigidbody2D component from 'Discrete' (the default value) to 'Continuous' or 'Continuous Dynamic'. Fixing this sort of issue (collision errors for fast-moving objects) is exactly what those options are for.
Source: http://docs.unity3d.com/Manual/class-Rigidbody.html