So i am just getting started with Unity and I am simply creating a basic game just to improve my knowledge. However, I have came across an error which i cannot seem to get my head around. The error is that i want to reset the player’s position back to their spawn position when they hit the plane, however when i use OnTriggerEnter (in this case) or OnCollisionEnter the collision/trigger is detected via a Debug.Log, however the position will not update to the startPos. The tags are correct, there is an RB on the plane the player is colliding with which is set to isKinematic, and the box collider on the plane is set as a trigger.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Xml.Serialization;
using UnityEngine;
using UnityEngine.UIElements;
public class Death_Reset : MonoBehaviour
{
public GameObject player;
private Vector3 spawnPos = new Vector3(0f, 0.8887f, 0f);
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
Debug.Log("Player reset");
player.transform.position = spawnPos;
}
}
}
This script is placed onto the plane which the player is colliding with.
Does line 10 refer to the prefab or the actual in-scene player? If it’s the prefab, you’re just setting your prefab (on disk) to the spawnPos.
If you name your public / serialized fields (variables) as simply “thing” (or in this case “player”) then you set yourself up for confusion.
If something is a prefab, name it that, such as public GameObject ThingPrefab; and only drag prefabs into it. Prefabs are “dead things (assets on disk) waiting to be Instantiated.”
If something is already in the scene or you Instantiate<T>() it in code, then store the result in a properly-named variable such as private GameObject ThingInstance;
Naming is hard… name things WELL to reduce your own confusion and wasted time.
EDIT: you probably want to get rid of some of those stray using statements at the top, unless you intend them to be there; I think some may even prevent you from building…
Does it make any difference if you replace your player-repositioning line of code with:
other.transform.position = spawnPos;
?
You’re already performing a tag check to determine whether or not the colliding object is the player, and “other” references that object (or rather its collider), so in this case it seems unnecessary/redundant to have a separate GameObject field for the player. I would just get rid of the “player” field all-together and use the “other” reference provided by OnTriggerEnter.
I replaced the line of code with what you suggested and sadly there is still no difference. Would looking at the movement script help at all? Also should there be any changes to the collision detection on the RigidBody of the trigger or does that not matter?
UPDATED SCRIPT
using UnityEngine;
public class Death_Reset : MonoBehaviour
{
private Vector3 spawnPos = new Vector3(0f, 0.8887f, 0f);
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
Debug.Log("Player reset");
other.transform.position = spawnPos;
}
}
}
EDIT: The Debug.Log works for anything, it’ll Log the other.transform.position of the object passing through, and it also recognises the name of the Instance passing through it which is “Player”.
I’m guessing your player is a character controller. You can’t just move a character controller to a new position. You have to disable the character controller component and then move it.
using UnityEngine;
public class Death_Reset : MonoBehaviour
{
private Vector3 spawnPos = new Vector3(0f, 0.8887f, 0f);
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
other.GetComponent<CharacterController>().enabled=false;
other.transform.position = spawnPos;
other.GetComponent<CharacterController>().enabled=true;
}
}
}