VR-oriented game in dev.
I have the two-hand-manipulation-script from the MRTK implemented, interacting with my objects works. Goal is to let the objects remain static in their position after interacting - theoretically working. As soon as I add collision with my environment (rigidbody # interactableGameObjects).
But as soon as I start interacting with them and let them actively collide with one of the scenery objects, they start tilting and floating without being willing to stop.
So I'm looking for an easy and not resource hungry way to stop any movement (translation, rotation) of my object after interacting with it - without adding gravity to it.
My main concern is not how to stop all the motion, as I could freeze all constraints of the objects rigidbody or set the Rigidbodys Velocity and angularVelocity = 0.
So my basic idea: "if(movement != 0), and if(object != grabbed), then trigger movement = freeze."
Haven't figured out, how to trigger this kind of event and how to check if item is grabbed or not. Or is there maybe an even easier way?
Thanks for any help!
Note: even if you take the sample scene of the twohandedmanipulation and add ridigbodys to the components, they start floating away without any interaction.
Tried so far:
Putting sample scene in same conditions
Expect vs result: Floating away objects instead of remain fixed in space.
You can use RigidbodyConstraints to freeze the object's position and rotation while retaining the collision properties.
GetComponenet<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
and to unfreeze:
GetComponenet<Rigidbody>().constraints = RigidbodyConstraints.none;
Related
I'm working on a 3D top down game in Unity 2021.3.4f1 (HDRP). In the game I have a player character that's already placed in the game scene before it starts and enemy characters that are instantiated at random spawn points within a certain distance of the player. The enemies and player can use melee attacks to attack each other. Once in a blue moon the player attacks will hit an enemy that the attacks aren't colliding with. This also happens vice versa, where an enemy's attacks will hit the player when the colliders aren't colliding. Otherwise the attacks and collision work flawlessly. I'm 90% sure that this wasn't occurring before I upgraded the engine from a prior 2019 version. Any ideas to as why this could be happening?
I'm using an attack pooling system, where attacks are created with their set info (i.e. attack damage, how many characters can be hit with a single attack etc.) and then thrown into a pool of attack objects. After the attack is registered and has finished, it's deregistered and kept in the pool for further use. I'm using a bool return method called IsCollided that takes in the attacks information as a parameter to detect the collision:
private bool IsCollided(AttackInfo info)
{
foreach (KeyValuePair<TriggerDetector, List<Collider>> data in
control.animationProgress.CollidingBodyParts)
{
foreach (Collider collider in data.Value)
{
foreach (AttackPartType part in info.AttackParts)
{
if (info.Attacker.GetAttackingPart(part) == collider.gameObject)
{
//We want to get the attack scriptable object
control.animationProgress.Attack = info.AttackAbility;
//We also want to get the attacker
control.animationProgress.Attacker = info.Attacker;
//We also want to get the damaged trigger
control.animationProgress.DamagedTrigger = data.Key;
//And then we return true because the attack has collided
return true;
}
}
}
}
//Otherwise it hasn't collided
return false;
}
Basically what I'm trying to say is that attacks will sometimes trigger hit reactions when they're not actually colliding with another character. you could be 15 feet away from a character and you'll collide with them. Most of the time it works when it should. But on a rare occasion this issue occurs.
I'm using a "TriggerDetector.cs" script that has an OnTriggerEnter() method that stores all of the collisions that interact with each character's colliders in a list. Those are then removed from the list using an OnTriggerExit() method that removes the collided with objects when the collision is no longer occurring. Aside from that there's tons of checks which detect if the attack is allowed to collide. There's no issues with that though as the attacks always collide when they should be aside from this issue.
Any help would be greatly appreciated!
I speculate that your system for adding and removing colliders may not work in all cases.
Specifically, I believe that ontriggerexit is not always called correctly, or there is some other problem in the method which, however, I cannot see because you have not published it.
I can advise you to use a different system: instead of using collisions, you can check every frame or every short time with a coroutine, if there are enemies within your area.
To do this, you can study how circles work in mathematics and how you can use them to check if an object is within the area around you.
Since 2019 Unity has made many changes and has probably changed, perhaps making it worse, the collision system.
If you need help with the advice on using the circumference, I can help you, perhaps by opening another question.
If I helped you, you could thank me by marking my answer as accepted: I would be grateful :)
P.S. Instead of foreach use for - it's much better for performance.
I am currently stuck on a problem where I want to move a gameObject closer/farther to me (the HoloLens camera) when my hand forward/backward. Well, I have correctly implemented the logic to move the object closer/farther but couldn't work my way through determining the movement of the hand.
I am using HoloToolkit's IManipulationHandler interface to move the object and this is the main logic that I am using right now:
void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
{
transform.position = Vector3.MoveTowards(objectPosition, cameraPosition,
- (eventData.CumulativeDelta * ManipulationSpeed).z);
}
(It only works fine when I don't change my position)
This is another logic I used:
void IManipulationHandler.OnManipulationUpdated(ManipulationEventData eventData)
{
transform.position = Vector3.MoveTowards(objectPosition, cameraPosition,
Vector3.Distance(cameraPosition, eventData.CumulativeDelta));
}
According to above logic whenever I move my hand (forward or backward) the object always comes closer, because the distance b/w the two vectors always increases at first.
Kindly help me with this issue. Thankyou.
Note: I want to rotate the object when my hand drags left/right and to move the object closer/farther when my hand drags forward/backward.
You may check out HandDraggable script from MixedRealityToolkit.
Looks like you are still using the HoloToolkit (now on the htk_development brunch), you can actually use the TwoHandManipulatable to achieve that. Otherwise, you may have to write your own solver. I don't recommend people to implement that from scratch, it is painful.
With TwoHandManipulatable.cs, you can move the object towards any direction. If you want to limit the direction (e.g. only towards the cam), you can override that in your own class.
In my application, I use voice command as a second choice to the hand gestures by modifying SimpleTagAlong scripts. Then associate this action with speech keywords "closer/further". In my experience with end users, they will thank you for having the voice command.
Thankyou... But my problem got solved when I used INavigationHandler interface instead of IManipulationHandler. I worked like a charm. Thanks again.
I am just about to tackle a new project where the core game mechanic is covering up dead bodies killed by the mafia with leaves using a leafblower.
You need to cover them well enough to not draw attention when the police question you.
The only problem I can see with this project is how to create this leafblower mechanic.
Off the top of my head I can think of attaching an empty object to my leaf blower which has a constant [rigibody.AddExplosiveForce] that procs on mouse click but thats it.
What should I be looking at and what would be a logical way to create this? You do not need to write the whole code for me, I just wan't to know what tools or scripting API I need to consider.
Thank you :)
You could try continuous adding force using Rigidbody.AddForceAtPosition(). Or calculate directions and try Rigidbody.AddForce().
Basically Rigidbody.AddExplosionForce is working as Rigidbody.AddForce, but uses sphere to calculate Vector3. If you need to emit it continuously, you should just use it in FixedUpdate() and list of object you can get by using Raycasts or simple Trigger Collider, for example Capsule Collider.
You could use Collider Capsule like this ↑↑↑. And in OnTriggerEnter or OnCollisionEnter:
private void OnCollisionEnter(Collider other) {
if (other.gameobject.tag != "leaf") return;
// Your AddForce here.
// Also you can get exact point of collsion by using
// other.contacts and use this as AddForce argument.
}
I am fairly new to code, I know some of the basics but my knowledge is limited, so please let me know WHY in your answer if it's not too hard to explain, I'd like to learn rather than just be given the answer!
This code is the basic controls for a game i am making. I'll be explaining the premise of the game just so you're able to better grasp what my intent is.
The game will focus on the completion of mazes, however movement is restricted to only being able to go forward, and right. You may never do a u-turn, go left or go backwards.
With my current code, it is possible (VERY EASILY POSSIBLE) to just translate over the entire maze and the colliders for walls don't apply due to it being a translate, which to my understanding is essentially 'teleporting' it.
I've looked around on similar topics and discussions but I was unable to find any answers that addressed this kind of issue with colliders.
When the object collides with a 'wall' in my maze, I want the object to be reset to it's original position, or at the very least die, I'm not sure if that will affect the answer given, but just incase keep that in mind, thank you!
using UnityEngine;
using System.Collections;
public class Movement_Script : MonoBehaviour {
public float playerspeed = 1;
void Update () {
if(Input.GetKeyDown("up"))
{
transform.Translate(Vector3.up * 1);
}
if(Input.GetKeyDown("right"))
{
transform.Translate(Vector3.right * 1);
transform.Rotate(Time.deltaTime,0 ,-90);
}
}
}
When you control the transform, you are telling "Place this there".
So when you do:
transform.Translate(Vector3.up * 1); // multiplying by one is useless
you tell to displace the object by 0,1,0 from its current position. This is regardless of any environment. You still can detect collision by it won't be resolve by the engine, you would have to do it yourself.
Unity came up with a ready to use solution with the character controller component. It does the same as you do in your code but also perform a bunch of collision checks and resolve them. The latest version is actually using rigidbody for a more physical approach.
http://docs.unity3d.com/Manual/class-CharacterController.html
http://docs.unity3d.com/ScriptReference/CharacterController.Move.html
the Move method is the one to use for Unity to handle the whole process for you. I would recommend to install a basic four wall room with a few boxes here and there so that you get the grip of it. Then it will be easy to move on to do whatever you want with it, whether 2D or 3D movement.
So I'm working on a space game called Star Commander.
The progress was going beautifully until I decided I needed to implement some sort of physics. I'm mainly going to be needing Farseer Physics for collision detection.
Anyway, since it's a space game, when I am declaring my 'World' object:
private World world;
this.world = new World(Vector2.Zero);
I have no gravity. This causes a weird result. I can collide with objects, but once I stop colliding with them, that's it. I can no longer collide with them and will just go straight through them. However, with gravity:
private World world;
this.world = new World(new Vector2(0F, 1F));
Collision works beautifully.
I've tried looking around for help with Farseer, but a lot of the posts are dated and there are no real good sources for information and sadly, I'm pretty sure I'm not going to get the help I need here either.
The only thing I found whilst looking around was that with objects called "Geoms" I need to disable a property called "CollisionResponeEnabled" or something similar.
However the Geom object is no longer present in Farseer Physics 3 and has been totally replaced by Fixtures. Fixtures do not seem to have this property, however.
I can provide any source code that may help, but keep in mind I am still implementing the physics engine into my project and a lot of the code isn't final and kind of messy.
IMPORTANT EDIT:
After recording a short gif to demonstrate my issue, I found out that I can only collide with an object once, to collide with it again, I have to collide with a different object, but then cannot collide with that object until I collide with a different object.
Example:
It seems to me that your bodies might be "sleeping" after the collision. Have you tried setting SleepingAllowed = false on the bodies to see if this is the problem?