context to the problem: I've got multiple sorts of cubes set up, placed in an array. I've made it so every different cube has his own parent, so all the cubes are grouped together with the other cubes of the same type.
I'm trying to move all the cubes of the same type up in the air away from the others so it becomes more visible how many cubes of the same type there are. my thought was that when any of the child objects get clicked, all of the objects under that parent move; but so far no succes.
Anyone got any tips as to how this might be able to work?
Note that I don't intend to use raycast as it seems overly compicated for this purpose.
If your cubes have colliders you can use OnMouseDown, in a script attached to each cube:
void OnMouseDown()
{
transform.parent.transform.Translate(Vector3.up * WhateverDistance);
}
If your cubes dont have colliders you'll have to use raycast to detect which cube has been clicked
Related
I recently started having a look at game development with Unity and was trying to make a simple 2D character with basic movement abilities. This character is supposed to jump and move from side to side, but only if it is standing on something.
Now my question is: How do you check if a player is standing on something? / Get the distance to the next game object / collider beneath the player game object?
Would greatly apreciate any helpful answers and especially explanations on how exactly it works. Thanks!
To do this, you need to send a ray to detect the point of impact on the ground and then calculate the distance. The code below sends a ray from the center of your object down to the maximum height (3) and gives the size.
public LayerMask groundLayer;
public float maxRayLength = 3;
public void Update()
{
var hit = Physics2D.Raycast(transform.position, Vector3.down, maxRayLength, groundLayer.value);
if (hit) Debug.Log(hit.distance); // it will print current distance from pivot
}
If you want to calculate the height of the ray from the character's foot, there are two methods, one is subtracting half the height of the character from it.
Physics2D.Raycast(transform.position-transform.up*height, ....)
Next one is to use an empty object at the base of the character, which we refer to instead of the center.
public Transform pivot;
Then..
Physics2D.Raycast(pivot, ....)
There are a few ways of actually doing this.
The most usual although a bit complicated way of doing it for a beginner is using Raycasts. A Raycast is basically a small invisible line that starts and ends where you tell it to. If anything of a specific tag or layer is caught in it's crossfire you can basically pull that object from your code. Raycasts are used for a lot of things, most notably in Shooter games to shoot or in games like Skyrim to pickup objects and interact with them.
Another way to do this, which is a bit more popular in 2D games is to create a "feet" GameObject and make it the child of the player in the hierarchy. You can add a box collider on that GameObject and check the "IsTrigger". You can add a Tag to your ground objects and through your code using the OnTriggerEnter() and OnTriggerExit() Methods you can basically tell when your character is floating on air and when he is on ground.
Another popular method is to use the Physics.OverlapBox() Method which is pretty much the same as the Trigger Method but you are creating an invisible box (much like a raycast) and instead of only getting notified when Triggered (something enters or exits) you check if the invisible box is colliding with another object/tag/collider (which could be your ground).
There are also a few different things you can do with a Nav Mesh (mostly in 3D) but I think that for now these 3 should suffice!
My question is quite simple. How do I make a cube which has other game objects inside of it, and can detect when those objects collide with sides of the cube. I can just use a collider for each of the sides but I want to be able to shrink and grow the cube while the program is running. If I used a collider for each of the sides I would have to move each of them individually. Is there a way to use just one collider on the cube?
Place six flat cubes around with a thin collier box and then make parent them to an empty game object.
Hello I am having a problem and I dont know how to solve it.
I want to create a 3d puzzle where the player needs to move multiple 3D objects to put them together. I already know how to implemet the movement (LeanTouch) but I need a way to recognize when two objects touch each other in special places. Then I would use transform to combine them. Does anyone have an Idea how to solve this?
One way to solve this is to create child objects with the colliders in the specific places you want to detect collision at. Then in OnCollisionEnter() you can practically combine them by creating a new parent of the two objects. Here's an example of an approach I took:
I set up my colliders like this:
Then on the individual colliders I added this code. Front is just the tag attached to the collider shown in the hierarchy.
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Front"))
{
var newParent = new GameObject();
newParent.transform.SetParent(collision.transform.parent.parent); // Get the parent of the current gameobject the collider is attached to
collision.transform.parent.SetParent(newParent.transform); // Doing .parent because this is the child collider
transform.parent.SetParent(newParent.transform);
}
}
It's not perfect, but the result is that the objects were combined under the same parent.
Alternatively, you could simply make one cube the child of the other by removing NewParent and replacing it with collision.transform.parent.
You should probably use colliders for that, and then use the collision event
I'm prototyping a climbing system for my stealth game. I want to mark some edges so that the player can grab them, but I'm not sure how to approach it. I know I can add separate colliders, but this seems quite tedious. Instead, what I'd like to do is to mark mark the edges in the mesh. Can this be achieved? How?
You're probably better off storing that edge data externally (that is, elsewhere in your running game than in the mesh) in an accessible format, that said, if you truly want to embed it INTO the mesh...
Tuck the metadata into Mesh.colors or Mesh.uv2 like #Draco18s suggests. Most shaders ignore one or both of these. Of course, you'll be duplicating edge/face level info for each vertex on the face.
When a player tries to "grab" an edge, run your collision test, grab the face, grab any vertex on the face, and look up your edge/face info.
You could also, for example, attach your edge metadata collection to a script attached to the mesh's game object. So long as you can access your collection of edges when you need to perform the test, where you store it is an implementation detail.
If you have the ability to add nested objects in your mesh, you could create a primitive box that represents the desired ledge and collider size. When you import the mesh in Unity, the child mesh object will appear as a child gameObject with its own MeshRenderer. You can disable the MeshRenderer for the ledge and add a BoxCollider component to it. The collider will be automatically sized to match the primitive mesh.
Blender Nested Objects example
Unity Nested Objects example
If I instantiate a prefab like so:
GameObject asteroid = GameObject.Instantiate(thing2spawn);
//then set the location and some other stuff
The prefabbed asteroid's collisions do not register at all, but If I simply drag the asteroid into the scene, the collisions work exactly as expected.
Figured it out.
My asteroid object has two child objects which contain colliders that do different things. Hitting a certain part of the asteroid heals you, while hitting the other part damages you. These two children had rigid body components so when I set the speed of the asteroid (the parent object) in code, the two children wouldn't move with it. So it seemed like the colliders weren't working when really they were just left behind in some other place. Removing the rigid bodies from the children fixed the problem.
Weird.