How can I access variables from a clone of this Game Object in Unity C#?

47 Views Asked by At

I am trying to make a bunch of water particles bounce around a box and off of each other using Verlet integration. Currently I can spawn particles by pressing space using the Instantiate(); Method in another script. I can spawn as many balls in as I want, and it works just fine. However, to calculate the bounces off of each other is where I'm running into issues. Verlet requires the current position and the last position to calculate velocity which I need to calculate the bounces and currently I can't figure out how to get the velocity from a clone of the prefab to another clone. Currently I am able to detect collisions by finding the distance between this ball and all the other balls and seeing if its less than the sum of their radii. This works fine for detecting collisions since I can easily get the transform of each game object. I was told by the all knowing chat GPT that I could either create a game object within the script and reference it in the inspector and access them that way but Im not sure how I would reference an object to itself. It also said I could make the instantiate all the gameobjects under a parent object and access the variables that way. Anyways heres my code.

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

public class WaterScript : MonoBehaviour
{


    //Variables for detecting collisions
    public float radius;
    public string cloneTag = "Water";
    private bool collide;
    


    //Variables for Verlet Integration

    public Vector2 pos;
    public Vector2 posLast = new Vector2 (0f, 0f);
    public Vector2 posNext;

    //Particle Properties
    public float mass = 1;
    public float elasticity = 1;


    //Parameters are current position and last position. Outputs next position
    //Calculates the objects next position based on where it is and where it was 
    //Called every frame but posNext can be overriden if it is calculated to be a collision in the next frame
    Vector2 movement(Vector2 pos, Vector2 posLast, float mass)
    {
        //BasicVerletForCalculatingMovement
        posNext[0] = pos[0] + (pos[0] - posLast[0]) + 0f / Time.deltaTime;
        posNext[1] = pos[1] + (pos[1] - posLast[1]) - 0.00000001f / Time.deltaTime;
        return posNext;

    }

    //Vector2 bounce(float x1, float y1, float v1, float x2, float y2, float v2)
    //{
        //v1f = (m1 - m2) * v1i / (m1 + m2) + 2 * m2 * v2i / (m1 + m2)

     //   float velX = (1 - 1) * velX / (2 + 2) + 2 * 1 * 0 / (1 + 1);
    //    float velX = (1 - 1) * velX / (2 + 2) + 2 * 1 * 0 / (1 + 1);
        //v1f = (m1 - m2) * v1i / (m1 + m2) + 2 * m2 * v2i / (m1 + m2)




    //}



    // Start is called before the first frame update
    void Start()
    {
        //movement(new Vector2 (0, 0),new Vector2 (0, 0), 1);
        //Debug.Log(posNext);
    }

    // Update is called once per frame
    void Update()
    {


        //Calls the movement function to calculate the next position
        




   
        //Create a List for all the GameObjects with the "Water" Tag
        GameObject[] waterObjects = GameObject.FindGameObjectsWithTag("Water");
        foreach (GameObject waterObject in waterObjects)
        {

            //Create a Vector for the position of each object
            Vector2 position = waterObject.transform.position;
            Vector2 nextposition = waterObject.transform.position;
            

            //Collision Detection Scripts
            //Pythagorean Theorem to detect if the distance between objects is less than the sum of their radius
            if (((transform.position.x - position[0]) * (transform.position.x - position[0])) 
                + ((transform.position.y - position[1]) * (transform.position.y - position[1])) < radius*radius)
            {
                

                //Detect if the collision is with itself
                if(position[0] == transform.position.x && position[1] == transform.position.y)
                {
                    //Always outputs collision with itself. I was to tired to figure out how to avoid the else statement
                } else
                {

                    //Where I want the bounce code to go


                    Debug.Log("Collide!");
                    

                }

            }

        }
        //defining the respective x and y coordinate constraints and bouncing the ball of the edge in the case of collision
        float wall1 = -15;
        float wall2 = 10;
        float floor1 = -15;
        float floor2 = 10;

        //simply setting the velocity to be opposite depending on which wall it collides with.
        if (transform.position.y < floor1)
        {
            float offset = pos[1] - floor1;
            pos[1] = floor1;
            posLast[1] = floor1 + ((-posLast[1] + floor1) + offset)*elasticity;

        }
        if (transform.position.x < wall1)
        {
            float offset = pos[0] - wall1;
            pos[0] = wall1;
            posLast[0] = wall1 + ((-posLast[0] + wall1) + offset)*elasticity;

        }
        if (transform.position.y > floor2)
        {

            float offset = pos[1] - floor2;
            pos[1] = floor2;
            posLast[1] = floor2 + ((-posLast[1] + floor2) + offset)*elasticity;

        }
        if (transform.position.x > wall2)
        {

            float offset = pos[0] - wall2;
            pos[0] = wall2;
            posLast[0] = wall2 + ((-posLast[0] + wall2) + offset)*elasticity;

        }

        movement(pos, posLast, 1);
        posLast = pos;
        pos = posNext;
        //Debug.Log(pos);
        //float velX = (pos[0] - posLast[0]) + 0f / Time.deltaTime;
        //float velY = (pos[1] - posLast[1]) - 0f / Time.deltaTime;

        transform.position = pos;




        if (transform.position.y < 0.078f)
        {
            //Debug.Log("CollideWithFloor!");
        }




    }


}

I have no ideas as to what to try. Maybe I could make a list of the positions of all the balls in the previous frame and calculate velocity from that? My fear is that this would be to Ram intensive. Also any suggestions for optimizations would much appreciated. I'm going to make another version of this Im just not sure if using Unitys game object feature is the correct way to go about it however I couldnt find any way to render the circles directly to the screen.

0

There are 0 best solutions below