Need help with prefab collider script

Hey guys, i got a problem. I have 2 players(sphere’s) created by same prefab (they have the same tag and script) and i want to swap their speed variables when they collide. I tried a lot of things but anything worked. Here is the script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class MovementMulti : NetworkBehaviour {

    private float aumentoA = 0.1f;
    [Header("Movement Variables")]
    [SerializeField] float vX = 0f;
    [SerializeField] float vY = 0f;
    [Header("Camera Position Variables")]
    [SerializeField] float cameraHeight = 15f;

    Transform mainCamera;
    Vector3 cameraOffset;

    void Start()
    {
        if (!isLocalPlayer) {
            Destroy(this);
            return;
        }

        cameraOffset = new Vector3(0f, cameraHeight, 0f);
        mainCamera = Camera.main.transform;
        MoveCamera();
    }

    void MoveCamera() {
        mainCamera.position = transform.position;
        mainCamera.rotation = transform.rotation;
        mainCamera.Translate(cameraOffset);
        mainCamera.LookAt(transform);
    }

    void  OnCollisionEnter(Collision other)
    {
        if (other.gameObject.tag.Equals("Player"))
        {
            //HERE I NEED THE SWAP vX and vY
       
        }
    }

    void Update()
    {
        float x = Input.acceleration.x;
        float y = Input.acceleration.y;

        float aumentoX = aumentoA * x;
        float aumentoY = aumentoA * y;


        if (x > 0)
        {
            vX += aumentoX;
        }
        else if (x < 0)
        {
            vX += aumentoX;
        }

        if (y > 0)
        {     
            vY += aumentoY;
        }
        else if (y < 0)
        {    
            vY += aumentoY;
        }


        transform.Translate(Vector3.right * vX * Time.deltaTime);
        transform.Translate(Vector3.forward * vY * Time.deltaTime);
        MoveCamera();
    }
}

Thanks you for your attention.

What have you tried and what is not working?

I think this is what you’re after. changed vY and vX to public, then you can access them

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
 
public class MovementMulti : NetworkBehaviour {
 
    private float aumentoA = 0.1f;
    [Header("Movement Variables")]
    [SerializeField]
    public float vX;
    [SerializeField]
    public float vY;
    [Header("Camera Position Variables")]
    [SerializeField] float cameraHeight = 15f;
 
    Transform mainCamera;
    Vector3 cameraOffset;
 
    void Start()
    {
        vX = 0f;
        vY = 0f;
        if (!isLocalPlayer) {
            Destroy(this);
            return;
        }
 
        cameraOffset = new Vector3(0f, cameraHeight, 0f);
        mainCamera = Camera.main.transform;
        MoveCamera();
    }
 
    void MoveCamera() {
        mainCamera.position = transform.position;
        mainCamera.rotation = transform.rotation;
        mainCamera.Translate(cameraOffset);
        mainCamera.LookAt(transform);
    }
 
    void  OnCollisionEnter(Collision other)
    {
        if (other.gameObject.tag = "Player") //what ever the tag is called
        {
            //HERE I NEED THE SWAP vX and vY
            other.gameObject.GetComponent<MovementMulti>().vX = vX;
            other.gameObject.GetComponent<MovementMulti>().vY = vY;
        }
    }
 
    void Update()
    {
        float x = Input.acceleration.x;
        float y = Input.acceleration.y;
 
        float aumentoX = aumentoA * x;
        float aumentoY = aumentoA * y;
 
 
        if (x > 0)
        {
            vX += aumentoX;
        }
        else if (x < 0)
        {
            vX += aumentoX;
        }
 
        if (y > 0)
        {   
            vY += aumentoY;
        }
        else if (y < 0)
        {   
            vY += aumentoY;
        }
 
 
        transform.Translate(Vector3.right * vX * Time.deltaTime);
        transform.Translate(Vector3.forward * vY * Time.deltaTime);
        MoveCamera();
    }
}

Here one of my attempts:

void  OnCollisionEnter(Collision other)
    {
        if (other.gameObject.tag.Equals("Player"))
        {
            foreach (var contact in other.contacts)
            {
                float x = contact.point.x - transform.position.x;
                float y = contact.point.z - transform.position.z;
                //if x posivite move right negative left
                //if y positive up negative down
                if (x >= 0)
                {
                    float aux = vY;
                    float aux2 = vX;
                    vY = other.gameObject.GetComponent<MovementMulti>().vZ;
                    vX = other.gameObject.GetComponent<MovementMulti>().vX;
                    other.gameObject.GetComponent<MovementMulti>().vY = aux;
                    other.gameObject.GetComponent<MovementMulti>().vX = aux2;
                }
            }
        }
    }

I tried something like johne5 too and i tried using triggers to get vX and vY onTriggerEnter and then swap it on collider.

I try now that but didnt worked to me. The two prefab sphere have been fired in the same direction, its probably because one prefab script is doing first than the other? Some idea for this not to happen?

right, if you have this script on both spheres, they are firing at the same time, swapping both at the same time. what is the end result you’re looking for?

I’m doing a multiplayer game where a prefab is created for each player at start of the game. The prefab have the sphere and this move script. So i need to create a separated script for each player to make that swap variables onCollider? I just want to make the spheres collide and fire in the opposite direction as realistic as possible if u know another way to do that would help me a lot. Thanks for your time and sorry for my bad english.

I think I came across a similar issue with someone once, and the solution I proposed then was to set a bool variable on collision .
Imagine, first collision registered tells the other object “I am going to set your value and you don’t set mine”
then in both OnCollisionEnter scripts, you check " was this variable set " and if yes, you don’t have to do anything, because you’ve already received the swapped value, and you reset that bool.
If the bool isn’t checked, of course, you swap the variables, and set the bool for the other collision gameobject.

Does that make sense?

bool bounced = false;
void OnCollisionEnter(Collision other)
    {
        if (other.gameObject.tag == "Player")
        {
            if(!bounced && !other.gameObject.GetComponent<MovementMulti>().bounced){
            bounced = true;
            other.gameObject.GetComponent<MovementMulti>().bounced = true;
            float aux = vY;
            float aux2 = vX;
            vZ = other.gameObject.GetComponent<MovementMulti>().vY;
            vX = other.gameObject.GetComponent<MovementMulti>().vX;
            other.gameObject.GetComponent<MovementMulti>().vY = aux;
            other.gameObject.GetComponent<MovementMulti>().vX = aux2;
            }
        }
    }

Now i try but still not working :(. I think that i will try another way to do the bounce probably setting vX and vY to 0 and then adding an addForce or something.

Adding force or what not could be a good idea whatever you think will work best.
You are mixing transform movement with collisions, also. Are you kinda trying to make your own physics or something?
If you moved with the physics engine, you could let it handle your collisions for your more properly maybe.

Upon reflection, I think my suggestion was decent (only sort of) – maybe not a best suited for your situation though :slight_smile:

Anyways, hope you get it working how you’d like.