- Home /
OnCollision not getting called,Collision problem in game.
I am trying to get my Player to "collect" wood when he collides with a tree. Both the Player and the trees are Prefab Rigidbodies with BoxColliders. Physics detects the collision and sends the player backwards, but the OnCollisionEnter() methed never gets called.
Here is the code for the TreeManager:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class TreeManager : MonoBehaviour { public GameObject TreePrefab; public int numberTrees = 18; private PlayerController playerControllerScript; private Vector3[] treeLocations; private int xpos, zpos;
// Use this for initialization
void Start()
{
playerControllerScript = GameObject.Find("Player").GetComponent<PlayerController>();
treeLocations = new Vector3[numberTrees];
for (int i = 0; i < numberTrees; i++)
{
TreePrefab.transform.localScale = new Vector3(0.38f, 0.52f, 0.38f);
xpos = 180 + Random.Range(0, 20);
zpos = 83 + Random.Range(0, 12);
treeLocations[i] = new Vector3(xpos, 0, zpos);
Instantiate(TreePrefab, new Vector3(xpos, 0, zpos), TreePrefab.transform.rotation);
print(TreePrefab.name + " at (" + treeLocations[i].x + ", " + treeLocations[i].y + ", " + treeLocations[i].z + ")");
}
}
// Update is called once per frame
void Update()
{
}
public void OnCollisionEnter()
{
playerControllerScript.woodTotal += 200;
print(gameObject.name + playerControllerScript.woodTotal);
Destroy(gameObject);
}
}
and the code for the PlayerController is:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class PlayerController : MonoBehaviour {
public float speed = 75;
public float woodTotal;
Rigidbody playerRb;
// Use this for initialization
void Start () {
playerRb = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void LateUpdate () {
if (Input.GetKeyDown(KeyCode.UpArrow))
{
playerRb.AddForce(Vector3.forward * speed * Time.deltaTime, ForceMode.Impulse);
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
playerRb.AddForce(Vector3.left * speed * Time.deltaTime, ForceMode.Impulse);
}
if (Input.GetKeyDown(KeyCode.DownArrow))
{
playerRb.AddForce(Vector3.back * speed * Time.deltaTime, ForceMode.Impulse);
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
playerRb.AddForce(Vector3.right * speed * Time.deltaTime, ForceMode.Impulse);
}
}
/*
void OnCollision(Collision collision)
{
if (collision.gameObject.CompareTag("Tree"))
{
woodTotal += 200;
Destroy(collision.gameObject);
}
}
*/
}
Any help would be greatly appreciated!,I am still new to Unity. My game needs the player to collide with a tree, pause a few seconds, then remove the tree from the scene and credit the player with 200 wood. Both the player and instantiated trees are Prefab Rigidbody with BoxCollider. The player simple bounces off the tree, so the Physics is working apparently. But the code inside the OnCollision() never gets executed.
public class TreeManager : MonoBehaviour {
public GameObject TreePrefab;
public int numberTrees = 2;
private PlayerController playerControllerScript;
private Vector3[] treeLocations;
private int xpos, zpos;
I placed this in the TreeManager script that spawns the trees
public class TreeManager : MonoBehaviour
{
public GameObject TreePrefab;
public int numberTrees = 18;
private PlayerController playerControllerScript;
private Vector3[] treeLocations;
private int xpos, zpos;
void Start()
{
playerControllerScript = GameObject.Find("Player").GetComponent<PlayerController>();
treeLocations = new Vector3[numberTrees];
for (int i = 0; i < numberTrees; i++)
{
TreePrefab.transform.localScale = new Vector3(0.38f, 0.52f, 0.38f);
xpos = 180 + Random.Range(0, 20);
zpos = 83 + Random.Range(0, 12);
treeLocations[i] = new Vector3(xpos, 0, zpos);
Instantiate(TreePrefab, new Vector3(xpos, 0, zpos), TreePrefab.transform.rotation);
print(TreePrefab.name + " at (" + treeLocations[i].x + ", " + treeLocations[i].y + ", " + treeLocations[i].z + ")");
}
}
public void OnCollisionEnter()
{
playerControllerScript.woodTotal += 200;
print(gameObject.name + playerControllerScript.woodTotal);
Destroy(gameObject);
}
The PlayerManager script simply moves the player around the screen with .AddForce. Any help would be appreciated! Thanks!
I did manage to fix that issue. I cannot get the gameObject of an instanced Prefab in order
to destroy it, so I will have to hard code all the trees? That seems really inefficient!
Answer by logicandchaos · Oct 03, 2021 at 02:43 PM
You did not properly call OnCollision(), you are missing the collider variable. You have to write the method the same or you will be creating your own overloaded method that will not be automatically called. Then you use the collider variable to get the gameObject that collided. Look at the collision method that you commented out.
Answer by TalkingBlah · Oct 03, 2021 at 04:38 PM
Hi here is the problem on TreeManager you call collision method without a collision parameter. void OnCollision(Collision collision) //Default method body of collision created by Unity OnCollisionEnter() // Collision method used by you
here is a code snippet that might fix your problem
void OnCollision(Collision collision) { if (collision.GetComponent()) { playerControllerScript = collision.GetComponent(); playerControllerScript.woodTotal += 200; print(gameObject.name + playerControllerScript.woodTotal); Destroy(gameObject); } else { Debug.Log(collision.gameobject.name + " is not player object") }
}
am just trying to edit u r code in the way it works i think you can optimize your code more better
Your answer