I’m trying to move an object back and forth or (sideways) once it hits a wall.
Walls have colliders and object has a collider and a rigidbody.
somehow, only the function update script moves the object. the calling function is not doing anything.
I know this is very simple but I can’t figure it out.
Attached is the script of what I have.
var state = 0;
function Update()
{
// Move the object back and forth along it’s x axis 1 unit/second.
rigidbody.AddRelativeForce(Vector3.right * Time.deltaTime);
state = 1;
OnCollisionEnter();// Call to function
OnCollisionExit();//call to function
}
function OnCollisionEnter()
{
if (state == 1)
{
rigidbody.AddRelativeForce(Vector3.left*Time.deltaTime);
state = 0;
return;
}
}
function OnCollisionExit ()
{
if (state == 0)
{
rigidbody.AddRelativeForce(Vector3.right*Time.deltaTime);
state = 1;
return;
}
}
I’m fairly certain that you don’t need to explicitly call OnCollisionEnter() or Exit() from your update function. They should be called automatically by the physics system. However, I am not sure if you need to set the colliders as Triggers…
on another note, use the tag for putting your code inside nice, easy to read blocks.
tried removing the function calls on update.
same prob. tried attaching triggers(is trigger). but everytime I do, objects goes thru wall, change the collision to ontrigger, same prob.
I’m still a newb so this may not be technically correct but…
Update() is being called as much as possible (ie, more than every frame) in a loop. So this…
function Update() {
rigidbody.AddRelativeForce(Vector3.right * Time.deltaTime);
state = 1;
}
…is always applying a force and setting state to 1.
Here’s a simplified version of the waypoint code I’ve been toying with. I “compiled” it here so if it doesn’t work out let me know.
Seek…
var target : GameObject; // target 'waypoint', mark as a trigger.
var speed=20; // force speed
var rotationSpeed = 0.5; // rotation speed
function Update() {
targetRotation = Quaternion.LookRotation(target.transform.position - transform.position);
str = Mathf.Min(rotationSpeed * Time.deltaTime, 1);
var myRotation = Quaternion.Lerp (transform.rotation, targetRotation, str);
transform.rotation = myRotation;
rigidbody.AddRelativeForce (Vector3.fwd * speed);
}
function OnTriggerEnter (other : Collider) { // hit the waypoint, get the next.
var script : Guide = target.GetComponent(Guide);
if (!script) return;
target = script.nextTarget;
}
Guide…
var nextTarget : GameObject;
Update() {}
You’ll add a couple new empty game objects and mark them as triggers. Add the Guide script to them and point them to the nextTarget. Then put the Seek script on whatever you want moving from waypoint to waypoint.
Trigger colliders aren’t solid. They’re more like proximity sensors which emit the OnTriggerEnter/Stay/Exit() events when something touches them. Therefore triggers are no use if you actually want to bounce off the wall. In that case, you’d just us ordinary non-trigger colliders and OnCollisionEnter/Stay/Exit().
Just for clarity, this isn’t right. Update() is called exactly once per frame. On the other hand, FixedUpdate() is called more frequently than once a frame (as specified in the physics settings).
I can initially move the object to desired location but cannot move it back once it hits the wall.
tried using transform.translate instead of rigidbody.
I also added var target:Transform; and put the script on the object that I want to move same prob. I also put the script on the wall that’s going to be hit and same prob. Only the first script movement is being executed, once it hits the wall the object just stays there.
I was able to use the OnCollisionEnter/Exit on one of the floors to change the color and was using the same logic(transform.translate instead of render.material) for this move object sideways, somehow the move object sideways is not doing what it’s suppose to do.
Here’s one of the script that I was trying.
This one goes to the longest wall where 4 colliders will hit it on different location
var target1:Transform;
var target2:Transform;
var target3:Transform;
var target4:Transform;
function OnCollisionEnter()
{
target1.transform.Translate(Vector3.leftTime.deltaTime);
target2.transform.Translate(Vector3.rightTime.deltaTime);
target3.transform.Translate(Vector3.leftTime.deltaTime);
target4.transform.Translate(Vector3.rightTime.deltaTime);
}
Here’s another one that will go to some shorter walls.
Been playing with the function Update, FixedUpdate, OnAwake, LateUpdate and still same prob.
var target:Transform;
function FixedUpdate()
{
target.transform.Translate(Vector3.rightTime.deltaTime);
}
function OnCollisionEnter(collision:Collision) //tried this with just OnCollisionEnter() same prob.
{
target.transform.Translate(Vector3.leftTime.deltaTime);
}
I’m just trying to accomplish a sideways movement everytime the object hits a wall.
Object moved to right, hit wall then move to left, then hit wall on other side then move to right again.
Hi,
your function OnCollisionEnter will not cause your object to move at all. first it moves to the left, then to the right, to the left and to the right again. This all happens in 1 time.
What I would do is turn your object by 180 degrees when OnCollisionEnter is true. Check out the documentation on quaternions.
do a transform.rotation, and multiply the .x and .z of transform.translate by -1 (if the x speed is 50, it will become -50, etc). Keep the .y the same.
the script below will move it to the left and will only moved to the right if “My FPS is the one colliding with it” on OnStay function.
at least I got some progress moving the SOB to the right but not the way I wanted it. Added OnStay just to see what will happen and that’s when the object will move the otherway if my FPS has an OnStay contact with it, if I detach it stops.
the script is attached to the movingwall.
appreciate any enlightenment/guidance on this one.
Thanks,
Ray
var target:Transform;
var WallLeft:Collider;
var wallRight:Collider;
function FixedUpdate()
{
transform.Translate(Vector3.left*Time.deltaTime);
Still can’t move the object the other way.
below is the script I’m working on.
var target:Transform;
var WallLeft:Collider;
var wallRight:Collider;
rigidbody.freezeRotation = true;
var contact:ContactPoint;
function FixedUpdate()
{
transform.Translate(Vector3.left*Time.deltaTime);
}
function OnCollisionEnter(collision:Collision)
{
//for (var contact : ContactPoint in collision.contacts)
//{
if(target.collider WallLeft.collider == contact)
{
target.transform.TransformDirection(Vector3.right);
target.transform.Translate(Vector3.right*Time.deltaTime);
}
else if(target.collider wallRight.collider == (contact))
{
transform.TransformDirection(Vector3.left);
transform.Translate(Vector3.left*Time.deltaTime);
}
// }
}
function OnCollisionStay(collision : Collision)
{
// Check if the collider we hit has a rigidbody
// Then apply the force
for (var contact : ContactPoint in collision.contacts)
{
print(contact.thisCollider.name + " hit " + contact.otherCollider.name);
// Visualize the contact point
Debug.DrawRay(contact.point, contact.normal, Color.white);
}
}
This line does nothing. Transform.TransformDirection() returns the vector you give it, but turned according to the rotation of the transform. If you don’t so anything with the return value, it gets discarded.
This is fine in principle, but you only do it in OnCollisionEnter(), so it only occurs when you actually touch the left wall. The moment you lose contact with the left wall, the code in FixedUpdate() moves you back into it again.
I don’t have time to write a proper example right now, but my suggestion is that you add a Vector3 property which is your current movement direction. In OnCollisionEnter(), set it to the vector you want to be travelling along (Vector3.right * Time.deltaTime * someFactor, perhaps). Then, in FixedUpdate(), do transform.Translate(myMovementVector) to keep moving along the last vector you specified.
Note also that you’ve commented out the ‘for(var contact : ContactPoint in collision.contacts)’ line at the moment, which means that ‘contact’ is not defined for the following two if() statements. You’ll need to either put it back in or just get the first collider.
Been playing with the code and come up with this one (below).
Somehow I don’t get no compile error, but the object won’t even move to the left(Initial move).
The only thing that I see(when running in game view) is the OnCollisionStay function which I cut and pasted to see how that thing works.
/*Move Object Sideways Only*/
var target:Transform;
var WallLeft:Transform;
var wallRight:Transform;
rigidbody.freezeRotation = true;
private var FirstMove = Vector3.left*Time.deltaTime;
function FixedUpdate()
{
target.transform.Translate(FirstMove);
}
function OnCollisionEnter(collision:Collision)
{
if(collision == target WallLeft)
{
FirstMove = Vector3.right*Time.deltaTime;
//target.transform.Translate(FirstMove);
return;
}
if(collision == target wallRight)
{
FirstMove = Vector3.left*Time.deltaTime;
//transform.Translate(FirstMove);
return;
}
}
function OnCollisionStay(collision : Collision)
{
// Check if the collider we hit has a rigidbody
// Then apply the force
for (var contact : ContactPoint in collision.contacts)
{
print(contact.thisCollider.name + " hit " + contact.otherCollider.name);
// Visualize the contact point
Debug.DrawRay(contact.point, contact.normal, Color.white);
}
}
function FixedUpdate()
{
transform.Translate(FirstMove*Time.deltaTime);
}
Incidentally, you should always use Time.fixedDeltaTime in FixedUpdate(), not Time.deltaTime. The latter is for use in Update(). If you use the wrong one, your timing is likely to be a bit irregular.
This is actually not the case. If you are inside a FixedUpdate function Time.deltaTime will return the fixedDeltaTime.
This is very convenient because it allows you to easily move code between Update and FixedUpdate.