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); } }
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(); } } }
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); }
public BallAgent PopLastBall() { BallAgent pop = Balls[BallCount - 1]; Balls[BallCount - 1] = null; BallCount -= 1; return(pop); }
public BallAgent PopSelectedBall() { BallAgent pop = SelectedBall; Balls[BallCount - 1] = null; BallCount -= 1; return(pop); }
public void DeSelectBall() { IsSelected = false; Vector3 newPos = SelectedBall.transform.localPosition; newPos.y = -1.5f + (BallCount - 1); SelectedBall.transform.localPosition = newPos; SelectedBall = null; }
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); } }
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; } }
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; }
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; }
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); }
// 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; } } } }
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(); } }
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); }
//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); } } } }