Commit 0dc317f0 authored by wayland bang's avatar wayland bang
Browse files

small changes to sight radius on wolf

parents 4c3d192d 07b751b8
using UnityEngine;
using System.Collections;
/*
*
* targetDetectRadius:
* 5 units - walks towards hero
*
*
* attackRange:
* 2 unit - zombie needs to be close enough to Hero for a good chance to walk towards
* and touch the Hero.
*/
public class ZombieAI : MonoBehaviour
{
/* Number of seconds until a new AI action is determined */
public float intervalPerNewAction_sec;
/* The time when the AI action will be updated */
private float nextAction_sec;
/* Current action to perform in Update() */
private DecisionTree.Action curAction;
/* Current target to walk towards for RandomWalk(). This gets
updated to a new value every time a new AI decision is made */
private Vector2 curRndWalkTarget;
/* Attached radar child for detecting nearby gameObjects*/
public GameObject radar;
public string targetLayer;
public float targetDetectRadius = 5.0f;
public float attackRange = 2.0f;
/* API's to dependent gameobjects */
private RadarCtrl radarCtrl;
//private ZombieCtrl zombieCtrl;
private enemyScript zombieCtrl;
/* My target */
private GameObject hero;
/* AI is represented as a decision tree */
private DecisionTree decTree;
/* Spawner that I came from */
private Transform parentSpawn;
private RadarCtrl parentSpawnRadarCtrl;
void Start ()
{
//this.zombieCtrl = (ZombieCtrl)GetComponent<ZombieCtrl> ();
this.hero = GameObject.FindGameObjectWithTag("Player");
this.radarCtrl = (RadarCtrl) this.radar.GetComponent<RadarCtrl>();
BuildDecisionTree ();
NextAction ();
this.parentSpawn = this.transform.parent;
if (this.parentSpawn != null)
this.parentSpawnRadarCtrl = (RadarCtrl)this.parentSpawn.GetComponentInChildren<RadarCtrl> ();
}
/* Determine new AI action to perform */
void NextAction()
{
this.nextAction_sec = this.intervalPerNewAction_sec;
this.curAction = this.decTree.Search ();
this.curRndWalkTarget = GetNewRandomWalkTarget ();
}
void Update ()
{
/* If it's time to update the next action to execute, do so */
if (Time.time > this.nextAction_sec) {
NextAction ();
this.nextAction_sec = Time.time + this.intervalPerNewAction_sec;
}
/* Perform AI action */
this.curAction ();
}
void BuildDecisionTree()
{
DecisionTree isTargetInsideThreatZoneTree = new DecisionTree ((DecisionTree.Decision) IsTargetInsideThreatZone);
DecisionTree isInRangeTree = new DecisionTree ((DecisionTree.Decision) IsInRange);
DecisionTree attackTree = new DecisionTree ((DecisionTree.Action) Attack);
DecisionTree advanceTree = new DecisionTree ((DecisionTree.Action) Advance);
DecisionTree isIdleAnimationTree = new DecisionTree ((DecisionTree.Action) IdleAnimation);
isTargetInsideThreatZoneTree.SetLeft (isInRangeTree);
isTargetInsideThreatZoneTree.SetRight (isIdleAnimationTree);
this.decTree = isTargetInsideThreatZoneTree;
}
/* Decision methods */
/* Hero (i.e. target) is considered a threat if he is near me, or near my spawn point, or fired at me */
bool IsTargetInsideThreatZone()
{
if (this.radarCtrl.GetNumNearby (this.targetLayer, this.targetDetectRadius) > 0)
return true;
if (this.parentSpawn != null)
return (this.parentSpawnRadarCtrl.GetNumNearby (this.targetLayer, this.targetDetectRadius) > 0);
else
return false;
}
/* Am I within attack range (i.e. short distance to walk up and touch the Hero)? */
bool IsInRange()
{
return (this.radarCtrl.GetNumNearby (this.targetLayer, this.attackRange) > 0);
}
/* Action methods */
/* Attack my moving towards the hero */
void Attack()
{
if (this.name == "Zombie(Clone)") {
Debug.Log("Action: Attack()");
}
this.zombieCtrl.WalkTowardsHero ();
}
void Advance()
{
this.zombieCtrl.WalkTowardsHero ();
}
/* Get a random position */
Vector2 GetNewRandomWalkTarget()
{
Vector2 rndVector = new Vector2 (Random.Range(-100f,100f),
Random.Range(-100f,100f));
Vector2 myPos = this.transform.position;
/* Destination */
Vector2 rndTarget = new Vector2 (myPos.x + rndVector.x, myPos.y + rndVector.y);
return rndTarget;
}
void IdleAnimation()
{
/* Idle. Do nothing */
}
}
\ No newline at end of file
using UnityEngine;
using System.Collections;
public class HeroGeneral : MonoBehaviour
{
void Awake ()
......@@ -18,4 +19,5 @@ public class HeroGeneral : MonoBehaviour
{
}
}
......@@ -50,18 +50,22 @@ public class HeroMovement : MonoBehaviour {
this.jump = true;
}
void OnCollisionStay2D(Collision2D coll) {
void OnCollisionStay2D(Collision2D coll)
{
string colTag = coll.gameObject.tag;
// sets grounded to true if Hero is in contact with the ground
if (coll.gameObject.tag == "ground") {
if (colTag == "ground" || colTag == "Item" || colTag == "Prop") {
grounded = true;
}
}
void OnCollisionExit2D(Collision2D coll) {
void OnCollisionExit2D(Collision2D coll)
{
string colTag = coll.gameObject.tag;
// sets grounded to false if Hero exits the ground
if (coll.gameObject.tag == "ground") {
if (colTag == "ground" || colTag == "Item" || colTag == "Prop") {
grounded = false;
}
}
......
......@@ -64,6 +64,10 @@ public class HeroInventory : MonoBehaviour
/* Used to determine if Hero is dead or not */
protected HeroDeathCtrl deathCtrl;
/* If mouse cursor is within Hero's mouse cursor horizontal threshold, do not update gun rotation,
otherwise, it will jitter. */
public float cursorHorThresh;
void Start ()
{
is_UI_inventory_opened = false;
......@@ -445,9 +449,16 @@ public class HeroInventory : MonoBehaviour
{
GameObject equippedGun = GetEquippedGun ();
/* Don't adjust rotation if mouse cursor is too close to Hero. Only update position. */
bool isUpdateRot = true;
Vector2 heroPos = this.transform.position;
Vector3 cursorAndHeroDist = mouseWorldPos - heroPos;
if (Mathf.Abs (cursorAndHeroDist.x) < this.cursorHorThresh)
isUpdateRot = false;
if (equippedGun != null) {
GunController gunCtrl = equippedGun.GetComponent<GunController>();
gunCtrl.CorrectOrientation (this.triggerFinger.transform.position, mouseWorldPos);
gunCtrl.CorrectOrientation (this.triggerFinger.transform.position, mouseWorldPos, isUpdateRot);
}
}
......
......@@ -3,14 +3,14 @@ using System.Collections;
public class DecisionTree
{
/* Note that Action nodes can have an optional Decision or Action node as its right child */
public delegate bool Decision();
public delegate void Action();
public Decision decision;
public Action action;
/*Leaf nodes will have an action and non-leaf nodes will have a decision*/
public DecisionTree left;
public DecisionTree right;
......@@ -61,18 +61,19 @@ public class DecisionTree
this.right = right;
}
public Action Search()
public void SearchAndExecute()
{
if (this.action != null)
{
return this.action;
}
else
{
if (this.action != null) {
this.action ();
if (this.right != null)
this.right.SearchAndExecute ();
}
else {
if (this.decision())
return this.left.Search();
this.right.SearchAndExecute();
else
return this.right.Search();
this.left.SearchAndExecute();
}
}
}
fileFormatVersion: 2
guid: 7580e7a14bdec4cf3a38f24b94dfae3f
guid: 465282958747eaa49866ab3354c56086
folderAsset: yes
timeCreated: 1476045420
licenseType: Free
......
......@@ -12,11 +12,9 @@ public class ItemGeneratorAI : MonoBehaviour
/* Time when chances will be updated */
protected float nextUpdateSec;
/* When Item Generator chances are needing to be updated, traverse through
these trees separately to determine the new chance values */
protected DecisionTree HP_tree;
protected DecisionTree coin_tree;
protected DecisionTree level_tree;
/* When Item Generator chances are needing to be updated, traverse through tree
to update item type chance */
protected DecisionTree tree;
/* The actions of the DecisionTree will be modifying the item drop chances
* (e.g. more health drops). Item drop chances are held below: */
......@@ -45,15 +43,7 @@ public class ItemGeneratorAI : MonoBehaviour
/* If it's time to refresh the Item Generator chances */
if (Time.time > this.nextUpdateSec)
{
resetChances();
DecisionTree.Action updateHPChances = this.HP_tree.Search();
DecisionTree.Action updateCoinChances = this.coin_tree.Search();
DecisionTree.Action updateRarityChances = this.level_tree.Search();
updateHPChances();
updateCoinChances();
updateRarityChances();
this.tree.SearchAndExecute ();
this.nextUpdateSec = Time.time + this.nextUpdateSec;
}
......@@ -61,54 +51,75 @@ public class ItemGeneratorAI : MonoBehaviour
void BuildDecisionTree()
{
/* Decision nodes */
DecisionTree isHeroHP_between_26_50_tree = new DecisionTree((DecisionTree.Decision) isHeroHP_between_26_50);
DecisionTree isHeroHP_above_50_tree = new DecisionTree((DecisionTree.Decision) isHeroHP_above_50);
DecisionTree isHeroCoins_between_26_50_tree = new DecisionTree((DecisionTree.Decision) isHeroCoins_between_26_50);
DecisionTree isHeroCoins_above_50_tree = new DecisionTree((DecisionTree.Decision)isHeroCoins_above_50);
DecisionTree isLevel2_tree = new DecisionTree((DecisionTree.Decision) isLevel2);
DecisionTree isLevel3_tree = new DecisionTree((DecisionTree.Decision) isLevel3);
/* Action nodes */
DecisionTree doNothing_tree = new DecisionTree((DecisionTree.Action) doNothing);
DecisionTree resetChances_tree = new DecisionTree((DecisionTree.Action) resetChances);
DecisionTree dblHPItemChance_tree = new DecisionTree((DecisionTree.Action) dblHPItemChance);
DecisionTree tplHPItemChance_tree = new DecisionTree((DecisionTree.Action) tplHPItemChance);
DecisionTree dblUnusualChance_tree = new DecisionTree((DecisionTree.Action) dblUnusualChance);
DecisionTree tplRareChance_tree = new DecisionTree((DecisionTree.Action) tplRareChance);
DecisionTree qplUniqueChance_tree = new DecisionTree((DecisionTree.Action) qplUniqueChance);
DecisionTree dblCoinChance_tree = new DecisionTree((DecisionTree.Action) dblCoinChance);
DecisionTree tplCoinChance_tree = new DecisionTree((DecisionTree.Action) tplCoinChance);
/* Decision tree of current health */
isHeroHP_above_50_tree.SetLeft(doNothing_tree);
isHeroHP_above_50_tree.SetRight(isHeroHP_between_26_50_tree);
isHeroHP_between_26_50_tree.SetLeft(dblHPItemChance_tree);
isHeroHP_between_26_50_tree.SetRight(tplHPItemChance_tree);
this.HP_tree = isHeroHP_above_50_tree;
/* Note that Action nodes can have an optional Decision or Action node as its right child */
/* Level subtree -> determines drop rarity chance */
DecisionTree isLevel3_tree = new DecisionTree((DecisionTree.Decision) isLevel3);
DecisionTree isLevel2_tree = new DecisionTree((DecisionTree.Decision) isLevel2);
DecisionTree dblUnusualChance_tree = new DecisionTree((DecisionTree.Action) dblUnusualChance);
DecisionTree tplRareChance_tree = new DecisionTree((DecisionTree.Action) tplRareChance);
DecisionTree qplUniqueChance_tree = new DecisionTree((DecisionTree.Action) qplUniqueChance);
qplUniqueChance_tree.SetRight (tplRareChance_tree);
tplRareChance_tree.SetRight (dblUnusualChance_tree);
isLevel3_tree.SetRight(qplUniqueChance_tree);
isLevel3_tree.SetLeft(isLevel2_tree);
isLevel2_tree.SetRight(tplRareChance_tree);
isLevel2_tree.SetLeft(dblUnusualChance_tree);
/* Subtree - HP above 50 */
DecisionTree is_hp_g50_and_coin_g50_tree = new DecisionTree((DecisionTree.Decision) isHeroCoins_above_50);
DecisionTree is_hp_g50_and_coin_26_50_tree = new DecisionTree((DecisionTree.Decision) isHeroCoins_between_26_50);
is_hp_g50_and_coin_g50_tree.SetRight (isLevel3_tree);
is_hp_g50_and_coin_g50_tree.SetLeft (is_hp_g50_and_coin_26_50_tree);
/* Decision tree of current coins */
DecisionTree hp_g50_dblCoinChance_tree = new DecisionTree((DecisionTree.Action) dblCoinChance);
hp_g50_dblCoinChance_tree.SetRight (isLevel3_tree);
isHeroCoins_above_50_tree.SetLeft(doNothing_tree);
isHeroCoins_above_50_tree.SetRight(isHeroCoins_between_26_50_tree);
DecisionTree hp_g50_tplCoinChance_tree = new DecisionTree((DecisionTree.Action) tplCoinChance);
hp_g50_tplCoinChance_tree.SetRight (isLevel3_tree);
isHeroCoins_between_26_50_tree.SetLeft(dblCoinChance_tree);
isHeroCoins_between_26_50_tree.SetRight(tplCoinChance_tree);
is_hp_g50_and_coin_26_50_tree.SetRight (hp_g50_dblCoinChance_tree);
is_hp_g50_and_coin_26_50_tree.SetLeft (hp_g50_tplCoinChance_tree);
this.coin_tree = isHeroCoins_above_50_tree;
/* Subtree - HP between 25 and 50 */
/* Decision tree of current level */
DecisionTree is_hp_25_50_and_coin_g50_tree = new DecisionTree((DecisionTree.Decision) isHeroCoins_above_50);
isLevel3_tree.SetLeft(qplUniqueChance_tree);
isLevel3_tree.SetRight(isLevel2_tree);
DecisionTree hp_25_50_dblCoinChance_tree = new DecisionTree((DecisionTree.Action) dblCoinChance);
hp_25_50_dblCoinChance_tree.SetRight (isLevel3_tree);
isLevel2_tree.SetLeft(tplRareChance_tree);
isLevel2_tree.SetRight(doNothing_tree);
is_hp_25_50_and_coin_g50_tree.SetRight (isLevel3_tree);
is_hp_25_50_and_coin_g50_tree.SetLeft (hp_25_50_dblCoinChance_tree);
this.level_tree = isLevel3_tree;
DecisionTree dblHPItemChance_tree = new DecisionTree ((DecisionTree.Action) dblHPItemChance);
dblHPItemChance_tree.SetRight (is_hp_25_50_and_coin_g50_tree);
/* HP below 25 */
DecisionTree tplHPItemChance_tree = new DecisionTree ((DecisionTree.Action) tplHPItemChance);
tplHPItemChance_tree.SetRight (isLevel3_tree);
/* Combine subtrees */
DecisionTree is_hp_25_50_tree = new DecisionTree((DecisionTree.Decision) isHeroHP_between_26_50);
is_hp_25_50_tree.SetRight (dblHPItemChance_tree);
is_hp_25_50_tree.SetLeft (tplHPItemChance_tree);
DecisionTree is_hp_g50_tree = new DecisionTree((DecisionTree.Decision) isHeroHP_above_50);
is_hp_g50_tree.SetRight (is_hp_g50_and_coin_g50_tree);
is_hp_g50_tree.SetLeft (is_hp_25_50_and_coin_g50_tree);
DecisionTree resetChances_tree = new DecisionTree ((DecisionTree.Action)resetChances);
resetChances_tree.SetRight (is_hp_g50_tree);
this.tree = resetChances_tree;
}
void InitDefaultChances()
......@@ -172,28 +183,23 @@ public class ItemGeneratorAI : MonoBehaviour
bool isLevel1()
{
Scene curScene = SceneManager.GetActiveScene();
return (curScene.name == "Level1");
return (curScene.name == "level1");
}
bool isLevel2()
{
Scene curScene = SceneManager.GetActiveScene();
return (curScene.name == "Level2");
return (curScene.name == "level2");
}
bool isLevel3()
{
{
Scene curScene = SceneManager.GetActiveScene();
return (curScene.name == "Level3");
return (curScene.name == "level3");
}
/* Action methods */
void doNothing()
{
}
void resetChances()
{
/* Deep copy our default chances to the Item Generator */
......
......@@ -19,11 +19,15 @@ public class RandomItemCtrl : MonoBehaviour {
Item item = (Item)this.itemGenCtrl.GetRandomItem(this.type, this.subtype, this.rarity);
GameObject go = (GameObject)Instantiate(item.gameObject, this.transform.position, Quaternion.identity, null);
this.itemGenCtrl.RemoveCloneStrFromName(go);
this.itemGenCtrl.RemoveCloneStrFromName(go);
if (go.GetComponent<ItemCtrl> ().type == eItemType.COLLECTABLE)
go.GetComponent<Rigidbody2D> ().isKinematic = false;
/* Make spawned loot fly in the air as its dropped animation */
Vector2 spawnForce = new Vector2 (Random.Range(-50,50), Random.Range(100,200));
go.GetComponent<Rigidbody2D> ().AddForce (spawnForce);
Destroy(this.gameObject);
}
......
......@@ -237,7 +237,8 @@ public class GunController : ItemCtrl {
return (int) Random.Range (this.modMinDamage, this.modMaxDamage);
}
public void CorrectOrientation(Vector3 triggerFingerPos, Vector3 mouseWorldPos=default(Vector3))
public void CorrectOrientation(Vector3 triggerFingerPos, Vector3 mouseWorldPos=default(Vector3),
bool isUpdateRot=true)
{
bool isGunFacingRight = getDirection().x > 0f;
......@@ -245,8 +246,10 @@ public class GunController : ItemCtrl {
Vector2 fireDirection = mouseWorldPos - this.barrelTip.transform.position;
float fireDirectionDegAngle = Mathf.Atan2 (fireDirection.y, fireDirection.x) * Mathf.Rad2Deg;
this.transform.rotation = Quaternion.Euler (0, 0, fireDirectionDegAngle);
if (isUpdateRot) {
float fireDirectionDegAngle = Mathf.Atan2 (fireDirection.y, fireDirection.x) * Mathf.Rad2Deg;
this.transform.rotation = Quaternion.Euler (0, 0, fireDirectionDegAngle);
}
//Debug.Log (fireDirection.x + "_" + fireDirection.y + "_ " + fireDirectionDegAngle);
/* Flip gun vertically if facing left */
......
fileFormatVersion: 2
guid: e5a2f74f8da1243649141fc778c444bc
guid: af4ec3788c36956449373d9b101935d2
folderAsset: yes
timeCreated: 1480363099
timeCreated: 1481132541
licenseType: Free
DefaultImporter:
userData:
......
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
void Awake()
{
}
void Start ()
{
}
void Update ()
{
if (Input.GetButtonDown ("ResetGame"))
ResetGame ();
}
public void ResetGame()
{
GameObject hero = GameObject.Find ("Hero");
Destroy (hero);
SceneManager.LoadScene ("title");
}
}
fileFormatVersion: 2
guid: 13f96a2e9c6624f009f5ff2e091a118c
timeCreated: 1480213298
guid: fa229963a6a15ea429251eadb903d0c2
timeCreated: 1481132432
licenseType: Free
MonoImporter:
serializedVersion: 2
......
fileFormatVersion: 2
guid: a6da355ec2380413fb376fc5338dfc01
folderAsset: yes
timeCreated: 1479231508
guid: f2c94700faede1343a97200912f0f6e7
timeCreated: 1481132584
licenseType: Free
DefaultImporter:
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant: