示例#1
0
    private void OnCollisionEnter(Collision collision)
    {
        string    otherName  = collision.gameObject.name;
        BallAgent otherAgent = collision.gameObject.GetComponent <BallAgent>();

        // Sets a force multiplier that is a fraction of the magnitude of the relative velocity of the collision
        float forceMultiplier = 1 + collision.relativeVelocity.magnitude / 3;

        // Then store a variable that is the force multiplied by the force multiplier
        float energy = FORCE * forceMultiplier;

        // If colliding with an object whose name contains the string stored within "absorb"
        if (otherName.Contains(absorb))
        {
            Absorb(otherAgent, energy, 0.6f, 0.4f, 0.1f);
        }

        // If colliding with an object whose name contains the string stored within "destroy"
        else if (otherName.Contains(destroy))
        {
            Destroy(otherAgent, energy, 1.05f, 0.05f, 0.1f);
        }

        // If colliding with a smaller object whose name contains the string stored within "sameElement"
        else if (otherName.Contains(sameElement) && (otherAgent.gameObject.transform.localScale.x < transform.localScale.x))
        {
            Absorb(otherAgent, energy, 0.40f, 0.35f, 0.075f);
        }
    }
示例#2
0
    private void Overflow(BallAgent teamAgent, bool resurrection = false)
    {
        if (transform.localScale.x > 8)
        {
            Vector3 share = transform.localScale / 4;

            transform.localScale -= share;
            speed          -= share.x;
            rigidBody.mass -= share.x;

            teamAgent.transform.localScale += share;
            teamAgent.speed          += share.x;
            teamAgent.rigidBody.mass += share.x;

            if (resurrection)
            {
                if (team == "Yin")
                {
                    gameController.yinCount++;
                }
                else
                {
                    gameController.yangCount++;
                }

                teamAgent.transform.localPosition = new Vector3(0, 19, 0);
                teamAgent.Resurrect();
            }
        }
    }
示例#3
0
    private void Absorb(BallAgent otherAgent, float energy, float growthMultiplier, float shrinkMultiplier, float reward)
    {
        if (rewards)
        {
            if (otherAgent.team != team)
            {
                // Rewarding the agents for absorbing an enemy
                AddReward(reward);
                otherAgent.AddReward(-reward);

                if (playerRewards)
                {
                    friendlyPlayer.AddReward(reward);
                    // Penalizing the other agents for being absorbed by an enemy
                    enemyPlayer.AddReward(-reward);
                }
            }
            else
            {
                // Lesser reward for the agents involved in size balancing among teammates
                if (otherAgent.transform.localScale.x > transform.localScale.x)
                {
                    float halfReward = reward / 2;

                    AddReward(halfReward);
                    otherAgent.AddReward(halfReward);

                    if (playerRewards)
                    {
                        friendlyPlayer.AddReward(halfReward);

                        // Penalty for enemy player agent
                        enemyPlayer.AddReward(-halfReward);
                    }
                }
                // Penalizes the agent and player for feeding upon a smaller teammate
                else if (otherAgent.transform.localScale.x < transform.localScale.x)
                {
                    AddReward(-reward);
                    otherAgent.AddReward(-reward);
                    friendlyPlayer.AddReward(-reward);
                    enemyPlayer.AddReward(reward);
                }
            }
        }

        float growth = energy * growthMultiplier;
        float damage = energy * shrinkMultiplier;

        transform.localScale += new Vector3(growth, growth, growth);
        rigidBody.mass       += growth;
        speed += growth;

        otherAgent.gameObject.transform.localScale            -= new Vector3(damage, damage, damage);
        otherAgent.gameObject.GetComponent <Rigidbody>().mass -= damage;
        otherAgent.speed -= damage;

        SizeCheck(otherAgent);
    }
示例#4
0
    public BallAgent PopLastBall()
    {
        BallAgent pop = Balls[BallCount - 1];

        Balls[BallCount - 1] = null;
        BallCount           -= 1;

        return(pop);
    }
示例#5
0
    public BallAgent PopSelectedBall()
    {
        BallAgent pop = SelectedBall;

        Balls[BallCount - 1] = null;
        BallCount           -= 1;

        return(pop);
    }
示例#6
0
    public void DeSelectBall()
    {
        IsSelected = false;
        Vector3 newPos = SelectedBall.transform.localPosition;

        newPos.y = -1.5f + (BallCount - 1);
        SelectedBall.transform.localPosition = newPos;
        SelectedBall = null;
    }
示例#7
0
 public bool IsEqual(BallAgent ball)
 {
     if (Color.r == ball.Color.r && Color.g == ball.Color.g && Color.b == ball.Color.b && Color.a == ball.Color.a)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
示例#8
0
    public void SelectBall()
    {
        SelectedBall = Balls[BallCount - 1];

        if (SelectedBall != null)
        {
            IsSelected = true;
            Vector3 newPos = SelectedBall.transform.localPosition;
            newPos.y = 2.5f;
            SelectedBall.transform.localPosition = newPos;
        }
    }
示例#9
0
    public void PushBall(BallAgent ball)
    {
        if (BallCount == 4)
        {
            return;
        }

        Balls[BallCount] = ball;
        ball.transform.SetParent(BallParent);
        ball.transform.localPosition = new Vector3(0f, -1.5f + BallCount, 0f);

        BallCount += 1;
    }
示例#10
0
    public void AddBall(int ballId)
    {
        if (BallCount == 4)
        {
            return;
        }

        GameObject go   = GameObject.Instantiate(GameManager.instance.BallPrefabs[ballId]);
        BallAgent  ball = go.GetComponent <BallAgent>();

        go.transform.SetParent(BallParent);
        go.transform.localPosition = new Vector3(0f, -1.5f + BallCount, 0f);
        Balls[BallCount]           = ball;
        BallCount += 1;
    }
示例#11
0
    private void Destroy(BallAgent otherAgent, float energy, float damageMultiplier, float shrinkMultiplier, float reward)
    {
        if (rewards)
        {
            // Penalizing the other agent for taking damage
            otherAgent.AddReward(-reward);

            // Checking for friendly fire, then the agent causing the collision is penalized
            // And the enemy player is rewarded
            if (otherAgent.team == team)
            {
                AddReward(-reward);

                if (playerRewards)
                {
                    friendlyPlayer.AddReward(-reward);
                    enemyPlayer.AddReward(reward);
                }
            }
            // Otherwise this agent is rewarded and the player of the other agent is penalized
            else
            {
                AddReward(reward);

                if (playerRewards)
                {
                    friendlyPlayer.AddReward(reward);
                    otherAgent.friendlyPlayer.AddReward(-reward);
                }
            }
        }

        float shrinkage = energy * shrinkMultiplier;
        float damage    = energy * damageMultiplier;

        transform.localScale -= new Vector3(shrinkage, shrinkage, shrinkage);
        rigidBody.mass       -= shrinkage;
        speed -= shrinkage;

        otherAgent.gameObject.transform.localScale            -= new Vector3(damage, damage, damage);
        otherAgent.gameObject.GetComponent <Rigidbody>().mass -= damage;
        otherAgent.speed -= damage;

        SizeCheck(otherAgent);
    }
示例#12
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Vector2      rayPos = new Vector2(Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y);
            RaycastHit2D hit    = Physics2D.Raycast(rayPos, Vector2.zero, 0f);

            if (hit)
            {
                if (hit.transform.tag == "Player")
                {
                    if (SelectedTube == null)
                    {
                        TubeAgent tube = hit.transform.GetComponent <TubeAgent>();
                        tube.SelectBall();
                        SelectedTube = tube;
                    }
                    else
                    {
                        TubeAgent tube = hit.transform.GetComponent <TubeAgent>();
                        if (tube.BallCount < 4)
                        {
                            BallAgent ball = SelectedTube.PopSelectedBall();
                            tube.PushBall(ball);

                            SelectedTube = null;

                            //tube.CheckBalls(); if returns true play success animation particle etc.

                            CheckForWin();
                        }
                    }
                }
            }
            else
            {
                if (SelectedTube != null)
                {
                    SelectedTube.DeSelectBall();
                    SelectedTube = null;
                }
            }
        }
    }
示例#13
0
    private void SizeCheck(BallAgent agent)
    {
        if (agent.transform.localScale.x <= 1f)
        {
            if (rewards)
            {
                // Penalty if killing a teammate
                if (agent.team == team)
                {
                    AddReward(-0.3f);

                    if (playerRewards)
                    {
                        friendlyPlayer.AddReward(-0.3f);
                        enemyPlayer.AddReward(0.3f);
                    }
                }
                // Reward for killing an enemy
                else
                {
                    AddReward(0.3f);

                    if (playerRewards)
                    {
                        friendlyPlayer.AddReward(0.3f);
                    }
                }
            }

            // Checks which team the agent is on, and decrements the team counter accordingly

            if (agent.team == "Yin")
            {
                gameController.yinCount--;
            }
            else
            {
                gameController.yangCount--;
            }

            // Sets agent as inactive
            agent.Death();
        }
    }
示例#14
0
    private void ObserveDistance(GameObject obj, string other = null)
    {
        Vector3   pointA;
        Vector3   pointB;
        BallAgent objectAgent    = obj.GetComponent <BallAgent>();
        Collider  objectCollider = obj.GetComponent <Collider>();

        if (other == "absorb")
        {
            pointA = objectAgent.absorbTarget.GetComponent <Collider>().ClosestPointOnBounds(obj.transform.localPosition);
            pointB = objectCollider.ClosestPointOnBounds(objectAgent.absorbTarget.transform.localPosition);
        }
        else if (other == "destroy")
        {
            pointA = objectAgent.destroyTarget.GetComponent <Collider>().ClosestPointOnBounds(obj.transform.localPosition);
            pointB = objectCollider.ClosestPointOnBounds(objectAgent.destroyTarget.transform.localPosition);
        }
        else if (other == "predator")
        {
            pointA = objectAgent.predator.GetComponent <Collider>().ClosestPointOnBounds(obj.transform.localPosition);
            pointB = objectCollider.ClosestPointOnBounds(objectAgent.predator.transform.localPosition);
        }
        else if (other == "destroyer")
        {
            pointA = objectAgent.destroyer.GetComponent <Collider>().ClosestPointOnBounds(obj.transform.localPosition);
            pointB = objectCollider.ClosestPointOnBounds(objectAgent.destroyer.transform.localPosition);
        }
        else if (other == "mirror")
        {
            pointA = objectAgent.enemyMirror.GetComponent <Collider>().ClosestPointOnBounds(obj.transform.localPosition);
            pointB = objectCollider.ClosestPointOnBounds(objectAgent.enemyMirror.transform.localPosition);
        }
        else
        {
            pointA = GetComponent <Collider>().ClosestPointOnBounds(obj.transform.localPosition);
            pointB = objectCollider.ClosestPointOnBounds(transform.localPosition);
        }

        // Finds the absolute distance between the two points
        float distanceFromObject = Vector3.Distance(pointA, pointB);

        AddVectorObs(distanceFromObject);
    }
示例#15
0
    //Observes teammate vector (x, z) position, and x scale if either "elementA" or "elementB" conditions are true
    private void ObserveTeammate(GameObject teammate)
    {
        if (self != teammate)
        {
            if (teammate.GetComponent <Rigidbody>().useGravity)
            {
                thisSurfaceToTargetSurface = GetComponent <Collider>().ClosestPointOnBounds(teammate.transform.localPosition);
                targetSurfaceToThisSurface = teammate.GetComponent <Collider>().ClosestPointOnBounds(transform.localPosition);

                float   distanceToTeammate  = Vector3.Distance(thisSurfaceToTargetSurface, targetSurfaceToThisSurface);
                Vector3 directionToTeammate = (teammate.transform.localPosition - transform.localPosition).normalized;

                AddVectorObs(distanceToTeammate);
                AddVectorObs(directionToTeammate.x);
                AddVectorObs(directionToTeammate.z);

                BallAgent teamAgent = teammate.GetComponent <BallAgent>();

                // Checks if the agent can absorb or be absorbed by the teammate
                // Also used to reward the agent's player for maximizing or minimizing distance
                if (name.Contains(teamAgent.absorb) | teammate.name.Contains(absorb))
                {
                    float teamMateScale = teammate.transform.localScale.x;
                    float thisScale     = transform.localScale.x;

                    AddVectorObs(teamMateScale - thisScale);

                    // If the teammate can absorb this agent
                    if (name.Contains(teamAgent.absorb))
                    {
                        // Checks if getting too big, then will share size equally with teammate
                        Overflow(teamAgent);

                        if (playerRewards)
                        {
                            // If the teammate is smaller than this agent
                            if (teamMateScale < thisScale)
                            {
                                // Very small constant negative reward for keeping away based off distance
                                friendlyPlayer.AddReward(-distanceToTeammate / 1000000000);
                            }
                            else
                            {
                                friendlyPlayer.AddReward(distanceToTeammate / 1000000000);
                            }
                        }
                    } // If the agent is able to absorb the teammate
                    else
                    {
                        if (playerRewards)
                        {
                            // If the teammate is larger than this agent
                            if (teamMateScale > thisScale)
                            {
                                // Very small negative reward for keeping away based on distance
                                friendlyPlayer.AddReward(-distanceToTeammate / 1000000000);
                            }
                            else
                            {
                                friendlyPlayer.AddReward(distanceToTeammate / 1000000000);
                            }
                        }
                    }
                } // If the agent can destroy, or be destroyed by the teammate
                else if (playerRewards && (name.Contains(teamAgent.destroy) | teammate.name.Contains(destroy)))
                {
                    // Very small constant reward for keeping away based on distance
                    friendlyPlayer.AddReward(distanceToTeammate / 1000000000);
                }
            }
            else
            {
                AddVectorObs(0);
                AddVectorObs(0);
                AddVectorObs(0);

                BallAgent teamAgent = teammate.GetComponent <BallAgent>();

                if (name.Contains(teamAgent.absorb) | teamAgent.name.Contains(absorb))
                {
                    AddVectorObs(0);

                    Overflow(teamAgent, true);
                }
            }
        }
    }