Home > database >  Collisions won't work with instantiated prefabs
Collisions won't work with instantiated prefabs

Time:02-03

Alright so I have a collision script which works as in if I collide a gameobject with another object with the script attached it does register a collision.

The collision script I am using:

private void OnCollisionEnter(Collision collision)
    {
            Debug.Log("collision registered");
    }

However when I try to collided my instantiated prefabs with my object with my script attached a collision does not get registered.

Does anyone know why this is? I think it's to do with with the prefabs being a "Moveable" but I can't quite get to the bottom of the problem.

Script attached to the prefabs:

public class Moveable : MonoBehaviour
{
    public float _speedMetersPerSecond = 50f;
    public float resistance = 10f;
    public float current = 0f;
    public List<Moveable> moveables = new List<Moveable>();
    private Vector3? _destination;
    private Vector3 _startPosition;
    private float _totalLerpDuration;
    private float _elapsedLerpDuration;
    private Action _onCompleteCallback;
    public GameObject Electron;
    public Transform Lightbulb;
    public SliderChange SliderScript;
    public VMT2Counter script2;

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // THE LIGHTBULB PART IS FOR THE SPAWN POINT SO DO NOT DELETE
            Moveable NextOnPath = Instantiate(Electron, Lightbulb.position, Quaternion.identity).GetComponent<Moveable>();
            moveables.Add(NextOnPath.GetComponent<Moveable>());
            MoverController.instance.targets.Add(NextOnPath.GetComponent<Moveable>());
        }

        if (_destination.HasValue == false)
            return;

        if (_elapsedLerpDuration >= _totalLerpDuration && _totalLerpDuration > 0)
            return;

        _elapsedLerpDuration  = Time.deltaTime;
        float percent = (_elapsedLerpDuration / _totalLerpDuration);

        transform.position = Vector3.Lerp(_startPosition, _destination.Value, percent);

        if (_elapsedLerpDuration >= _totalLerpDuration)
            _onCompleteCallback?.Invoke();

        // resistance = SliderScript.slider.value;
        // current = script2.PotentialDifference / resistance;

    }

    public void MoveTo(Vector3 destination, Action onComplete = null)
    {
        var distanceToNextWaypoint = Vector3.Distance(transform.position, destination);
        _totalLerpDuration = distanceToNextWaypoint / _speedMetersPerSecond;

        _startPosition = transform.position;
        _destination = destination;
        _elapsedLerpDuration = 0f;
        _onCompleteCallback = onComplete;
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.name == "Resistor")
        { 
        Debug.Log("lol");
        _speedMetersPerSecond = 25f;
        }
    }
}

Another script which goes hand in hand with the Moveable script but is not attached to the prefab:

public class MoverController : MonoBehaviour
{
    public List<Moveable> targets;
    [SerializeField] private Moveable target;
    private List<Transform> _waypoints;
    private int _nextWaypointIndex;
    public static MoverController instance;

    void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(gameObject);
            return;
        }
        DontDestroyOnLoad(gameObject);
    }

    private void OnEnable()
    {
        MoveToNextWaypoint();
    }

    private void MoveToNextWaypoint()
    {
        for (int i = 0; i < targets.Count; i  )
        {
            if (targets[i] == null) continue;
            _waypoints = GetComponentsInChildren<Transform>().ToList();
            _waypoints.RemoveAt(0);
            var targetWaypointTransform = _waypoints[_nextWaypointIndex];
            targets[i].MoveTo(targetWaypointTransform.position, MoveToNextWaypoint);
            targets[i].transform.LookAt(_waypoints[_nextWaypointIndex].position);
            _nextWaypointIndex  ;

            if (_nextWaypointIndex >= _waypoints.Count)
                _nextWaypointIndex = 0;
        }
    }
}

[![A picture of the prefab][1]][1]

[1]: https://i.stack.imgur.com/uyuge.png*emphasized text*

Video which shows situation: https://clipchamp.com/watch/MXjnTKl2cqg

CodePudding user response:

The collider is a trigger:

Collider A Collider B Event triggered
Collider Collider Collision
Collider Trigger Trigger
Trigger Collider Trigger
Trigger Trigger Trigger

To fix this problem, either uncheck the box for it to collide normally, or change your event handler to detect triggers instead of colliders:

private void OnTriggerEnter(Collider other) {
    Debug.Log("collision registered");
}

See here for more https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html :)

It is also worth pointing out that if neither of your objects have rigidbodies on, the event will not fire. If you need it to fire but don't want all of the rigidbody physics, you can add one but tick the isKinematic box.

  • Related