- Home /
How to place an object at the centre of another and move it along.
For a skating game I am doing raycasting to detect the player being ontop of a mesh with the tag "Metal Rail". The code I am currently writing needs to: Position the player at the middle of the rail In the direction the player is moving, push them along the rail at the current moving speed multiplied by another factor.
So skateSpeed is the speed we normally moving and grindSpeed is that extra boost of speed we get. What I am having trouble with is moving the player along and placing the player in the middle of the rail so we're not grinding far off the mesh. Here is my attempt in C#:
//Grinding
Vector3 down = transform.TransformDirection(Vector3.down);
if (Physics.Raycast(transform.position, down, out hit))
{
if (hit.collider.CompareTag("MetalRail"))
{
print("We're grinding!!!");
transform.Translate(0,Vector3.forward * Time.deltaTime * skateSpeed * grindSpeed,0);
transform.rotation = collider.GetComponent.rotation;
Grind(); //Animation cues
}
}
Please assist me in correctly performing the translation to move the player along and position the player at the centre of the rail. Many thanks!
Have you tried compensating for the "slipping of the rail" by simply setting the x or z of you player to the x or z of the rail?
Thanks for the prompt comment! I tried to in the transform.rotation = collider.GetComponent.rotation; but I don't think that part is quite right. I replaced the translation with transform.forward = Vector3.Normalize(new Vector3(0f, 0f, grindSpeed * skateSpeed)); and it makes the player stay still but it might be on the right track in terms of the grind movement.
Let's say your player's local x is the axis pointing forward. Couldn't you just move him along his z axis to center him once he's on the rail.
Vector3 newZ = new Vector3(transform.position.x, transform.position.y, hit.collider.transform.position.z); transform.position = newZ;
I'm not sure that would work in your case but I think it's worth a try.
I did:
if (hit.collider.CompareTag("$$anonymous$$etalRail")) { Vector3 newZ = new Vector3(transform.position.x, transform.position.y, hit.collider.transform.position.z); transform.position = newZ;
print("We're grinding!!!");
}
And it actually snaps the player to the middle of the current rail! Thanks! Positioning is well done!
So it works? I'll post the solution as an answer below then. Would you $$anonymous$$d selecting it as the correct answer so that we can close this question? Thanks.
Answer by Flash · Apr 22, 2012 at 01:05 AM
Let's say your player's local x is the axis pointing forward. Couldn't you just move him along his z axis to center him once he's on the rail.
if (hit.collider.CompareTag("MetalRail")) {
Vector3 newZ = new Vector3(transform.position.x, transform.position.y, hit.collider.transform.position.z);
transform.position = newZ;
}
This is partially an answer. The second part is actually pushing me forward. Your code makes the player positioned in the middle of the rail, which is what I asked for. But how do we push the player along?
I'll give you the credit of answering the question anyhow.
Well if we presume that the local x of you player is the forward direction you could simply go:
transform.position.x += SlideSpeed * Time.deltaTime;
When you've detected that the player is on the rail.
Oh man we're so close! The only thing to tackle now is storing in a temporary variable. I did:
Vector3 sliding = transform.position.x; transform.position.x += grindSpeed * Time.deltaTime;
transform.position = sliding;
but with no success. But hey, this error asside and we're done! Another thumbs up for you :)
In the code you just posted you declare a Vector3 variable called "sliding" and assign the x position of your objects transform (transform.position.x).. Well you see the x property of the transform.position is not a Vector3 but a float. What your code is doing is storing the x property of the position as a Vector3 (Which should be a float). You then move your object on the x axis (transform.position.x += grindSpeed * Time.deltaTime). Then you're "resetting" the position of your object (transform.position = sliding) which is not allowed since transform.position needs a Vector3 not a float (The variable "sliding" is a float in this case).
I'm not sure exactly what you want to do here so if you could explain a bit further that would be great.