Simple collision?

Hello!

I’m writing a fairly basic game to learn C# with, so I didn’t want to use any pre-made assets or scripts. I have a fps control system and everything is working great!

The player walks around a simple square room, and obviously shouldn’t be able to go through the walls. I can use OnCollisionEnter and OnCollisionExit, and they both work at detecting when the collider has intersected with something. However, this does not prevent the character from going through the walls and objects.

Is there an easy way to prevent 2 game objects from going through each other?

I can think of a few ways to do accomplish/fake the effect I’d like, such as only allowing movement in a direction up to a certain value, but I feel like it wouldn’t be useful in an actual game, because I won’t always be dealing with prefect squares.

What would be the ‘official’ way of preventing an object from intersecting?

If OnCollisionEnter and OnCollisionExit is working, i think you are using Translate to move the player. To prevent the player from going through the walls you must add character controller component to your player and use CharacterController.move instead.

This code is from Unity Scripting Reference.

PD: Excuse my english.


using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    public float speed = 6.0F;
    public float jumpSpeed = 8.0F;
    public float gravity = 20.0F;
    private Vector3 moveDirection = Vector3.zero;
    void Update() {
        CharacterController controller = GetComponent<CharacterController>();
        if (controller.isGrounded) {
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;
            if (Input.GetButton("Jump"))
                moveDirection.y = jumpSpeed;
            
        }
        moveDirection.y -= gravity * Time.deltaTime;
        controller.Move(moveDirection * Time.deltaTime);
    }
}

Ok, so I think I figured it out… in case anyone else is interested, here’s what I did.

I put a collider around my character, and added a rigid body to it, as needed by the OnCollisionEnter() script. Using OnCollisionEnter, I have it calculate the normal direction of the object with which it collides, and set a hit boolean to true false to see if contact was made. Then, I use the x and z components of that normal vector in the translation of my character when the collision is true.

It works relatively just like I wanted it to, but I have to divide the components by 1000 so that it doesn’t jump back and forth rapidly as you try to enter the wall.

Code in C#:

CollisionDetect script:

using UnityEngine;
using System.Collections;



public class CollisionDetect : MonoBehaviour {
	
	public static bool Hit = false;
	public static Vector3 Wall = new Vector3(0,0,0);
	
	public void Awake () {

	Wall = new Vector3(0,0,0);
	Hit = false;
		
    }
	
	void OnCollisionEnter(Collision collision) {
		
		ContactPoint contact = collision.contacts[0];
		Wall = contact.normal;
		Hit = true;
		
	}
	
	void OnCollisionExit(Collision collisionInfo) {
		Hit = false;
		
    }
	
}

WASDmovement Script:

using UnityEngine;
using System.Collections;

public class WASDmovement : MonoBehaviour {
	
	public float speed = 10f;
	public float rotate = 90f;
	
    void Update() {
		
		if(CollisionDetect.Hit == true){
				
				transform.Translate ((CollisionDetect.Wall.x)/1000,0,(CollisionDetect.Wall.z)/1000, Space.World);
			    float y = rotate * Time.smoothDeltaTime * Input.GetAxis("Horizontal");
				Debug.Log(CollisionDetect.Wall);
			    transform.Rotate(0, y, 0);		
		}
		
		
		else{
	
		float moveForward = speed * Time.smoothDeltaTime * Input.GetAxis("Vertical");
		float y = rotate * Time.smoothDeltaTime * Input.GetAxis("Horizontal");
		transform.Translate (0, 0, 1 * moveForward);		
        transform.Rotate(0, y, 0);
			
		}
		
    }
}