unity官方demo学习之Stealth(二十)敌人视听范围
2015-10-05 11:51
441 查看
为敌人添加脚本DoneEnemySight
参数:(公有)敌人的视角范围
判断敌人是否看见玩家
每个敌人独立的变量
用于储存敌人听到玩家脚步声/喊叫声的位置
(私有)
using UnityEngine; using System.Collections; public class DoneEnemySight : MonoBehaviour { public float fieldOfViewAngle = 110f; // Number of degrees, centred on forward, for the enemy see. public bool playerInSight; // Whether or not the player is currently sighted. public Vector3 personalLastSighting; // Last place this enemy spotted the player. private NavMeshAgent nav; // Reference to the NavMeshAgent component. private SphereCollider col; // Reference to the sphere collider trigger component. private Animator anim; // Reference to the Animator. private DoneLastPlayerSighting lastPlayerSighting; // Reference to last global sighting of the player. private GameObject player; // Reference to the player. private Animator playerAnim; // Reference to the player's animator component. private DonePlayerHealth playerHealth; // Reference to the player's health script. private DoneHashIDs hash; // Reference to the HashIDs. private Vector3 previousSighting; // Where the player was sighted last frame. void Awake () { // Setting up the references. nav = GetComponent<NavMeshAgent>(); col = GetComponent<SphereCollider>(); anim = GetComponent<Animator>(); lastPlayerSighting = GameObject.FindGameObjectWithTag(DoneTags.gameController).GetComponent<DoneLastPlayerSighting>(); player = GameObject.FindGameObjectWithTag(DoneTags.player); playerAnim = player.GetComponent<Animator>(); playerHealth = player.GetComponent<DonePlayerHealth>(); hash = GameObject.FindGameObjectWithTag(DoneTags.gameController).GetComponent<DoneHashIDs>(); // Set the personal sighting and the previous sighting to the reset position. personalLastSighting = lastPlayerSighting.resetPosition; previousSighting = lastPlayerSighting.resetPosition; } void Update () { // If the last global sighting of the player has changed... if(lastPlayerSighting.position != previousSighting) // ... then update the personal sighting to be the same as the global sighting. personalLastSighting = lastPlayerSighting.position; // Set the previous sighting to the be the sighting from this frame. previousSighting = lastPlayerSighting.position; // If the player is alive... if(playerHealth.health > 0f) // ... set the animator parameter to whether the player is in sight or not. anim.SetBool(hash.playerInSightBool, playerInSight); else // ... set the animator parameter to false. anim.SetBool(hash.playerInSightBool, false); } void OnTriggerStay (Collider other) { // If the player has entered the trigger sphere... if(other.gameObject == player) { // By default the player is not in sight. playerInSight = false; // Create a vector from the enemy to the player and store the angle between it and forward. Vector3 direction = other.transform.position - transform.position; float angle = Vector3.Angle(direction, transform.forward); // If the angle between forward and where the player is, is less than half the angle of view... if(angle < fieldOfViewAngle * 0.5f) { RaycastHit hit; // ... and if a raycast towards the player hits something... if(Physics.Raycast(transform.position + transform.up, direction.normalized, out hit, col.radius)) { // ... and if the raycast hits the player... if(hit.collider.gameObject == player) { // ... the player is in sight. playerInSight = true; // Set the last global sighting is the players current position. lastPlayerSighting.position = player.transform.position; } } } // Store the name hashes of the current states. int playerLayerZeroStateHash = playerAnim.GetCurrentAnimatorStateInfo(0).nameHash; int playerLayerOneStateHash = playerAnim.GetCurrentAnimatorStateInfo(1).nameHash; // If the player is running or is attracting attention... if(playerLayerZeroStateHash == hash.locomotionState || playerLayerOneStateHash == hash.shoutState) { // ... and if the player is within hearing range... if(CalculatePathLength(player.transform.position) <= col.radius) // ... set the last personal sighting of the player to the player's current position. personalLastSighting = player.transform.position; } } } void OnTriggerExit (Collider other) { // If the player leaves the trigger zone... if(other.gameObject == player) // ... the player is not in sight. playerInSight = false; } float CalculatePathLength (Vector3 targetPosition) { // Create a path and set it based on a target position. NavMeshPath path = new NavMeshPath(); if(nav.enabled) nav.CalculatePath(targetPosition, path); // Create an array of points which is the length of the number of corners in the path + 2. Vector3 [] allWayPoints = new Vector3[path.corners.Length + 2]; // The first point is the enemy's position. allWayPoints[0] = transform.position; // The last point is the target position. allWayPoints[allWayPoints.Length - 1] = targetPosition; // The points inbetween are the corners of the path. for(int i = 0; i < path.corners.Length; i++) { allWayPoints[i + 1] = path.corners[i]; } // Create a float to store the path length that is by default 0. float pathLength = 0; // Increment the path length by an amount equal to the distance between each waypoint and the next. for(int i = 0; i < allWayPoints.Length - 1; i++) { pathLength += Vector3.Distance(allWayPoints[i], allWayPoints[i + 1]); } return pathLength; } }
参数:(公有)敌人的视角范围
判断敌人是否看见玩家
每个敌人独立的变量
用于储存敌人听到玩家脚步声/喊叫声的位置
(私有)
相关文章推荐
- unity官方demo学习之Stealth(十九)敌人动画控制
- unity官方demo学习之Stealth(十八)敌人初步设定
- unity官方demo学习之Stealth(十七)电梯移动设定
- unity官方demo学习之Stealth(十六)双层门
- unity官方demo学习之Stealth(十五)单开门动画
- unity官方demo学习之Stealth(十四)钥匙卡设定
- unity官方demo学习之Stealth(十三)摄像机跟踪
- unity官方demo学习之Stealth(十二)角色生命值
- unity官方demo学习之Stealth(十一)角色移动
- unity官方demo学习之Stealth(十)散列ID
- unity官方demo学习之Stealth(九)角色动画控制器
- unity官方demo学习之Stealth(八)角色初步设定
- Unity 围住神经猫
- unity官方demo学习之Stealth(七)激光门
- unity官方demo学习之Stealth(五)游戏控制器
- unity官方demo学习之Stealth(四)屏幕渐变效果
- unity官方demo学习之Stealth(三)标签管理
- unity官方demo学习之Stealth(二)警报灯设定
- Unity之Navigation导航系统
- Unity3D 搭建优雅的UI框架