一、框架視圖
二宋彼、主要代碼
Indoor
AnimatorSetup
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimatorSetup {
public float speedDampTime=0.1f; //緩沖時(shí)間
public float angularSpeedDampTime = 0.7f;
public float angleResponseTime = 1f;
private Animator anim;
private HashIDs hash;
/// <summary>
/// 構(gòu)造函數(shù)
/// </summary>
public AnimatorSetup(Animator anim,HashIDs hash) {
this.anim = anim;
this.hash = hash;
}
public void Setup(float speed, float angle) {
float angularSpeed = angle / angleResponseTime;
anim.SetFloat(hash.speedFloat,speed,speedDampTime,Time.deltaTime);
anim.SetFloat(hash.angularSpeedFloat,angularSpeed,angularSpeedDampTime,Time.deltaTime);
}
}
FadeInOut
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// 屏幕淡入淡出效果
/// </summary>
public class FadeInOut : MonoBehaviour {
public float fadeSpeed=0.2f;
private bool sceneStarting = true;
//private GUITexture tex;
private RawImage tex;
void Start () {
//tex = this.GetComponent<GUITexture>();
tex = this.GetComponent<RawImage>();
//tex.pixelInset = new Rect(0,0,Screen.width,Screen.height);
}
void Update () {
if (sceneStarting)
{
StartScene();
}
}
//漸入
private void FadeToClear() {
tex.color = Color.Lerp(tex.color,Color.clear,fadeSpeed*Time.deltaTime);
}
//漸出
private void FadeToBlack() {
tex.color = Color.Lerp(tex.color,Color.black,fadeSpeed*Time.deltaTime);
}
/// <summary>
/// 進(jìn)入場(chǎng)景
/// </summary>
public void StartScene() {
FadeToClear();
if (tex.color.a<=0.05f)
{
tex.color = Color.clear;
//tex.enabled = false;
sceneStarting = false;
}
}
/// <summary>
/// 結(jié)束場(chǎng)景
/// </summary>
public void EndScene() {
sceneStarting = true;
FadeToBlack();
if (tex.color.a>=0.95f)
{
//SceneManager.LoadScene("Indoor");
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
/// <summary>
/// 進(jìn)入下一個(gè)場(chǎng)景
/// </summary>
public void NextScene() {
sceneStarting = true;
FadeToBlack();
if (tex.color.a >= 0.95f)
{
SceneManager.LoadScene("Outdoor");
}
}
}
fps_Crosshair
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 武器設(shè)置以及準(zhǔn)星繪制
/// </summary>
public class fps_Crosshair : MonoBehaviour {
public float length;
public float width;
public float distance;
public Texture2D crosshairTexture;
public GUIStyle lineStyle;
private Texture tex;
void Start () {
lineStyle = new GUIStyle();
lineStyle.normal.background = crosshairTexture;
}
void Update () {
}
/// <summary>
/// 繪制準(zhǔn)星
/// </summary>
void OnGUI() {
GUI.Box(new Rect((Screen.width-distance)/2-length,(Screen.height-width)/2,length,width),tex,lineStyle);
GUI.Box(new Rect((Screen.width+distance)/2,(Screen.height-width)/2,length,width),tex,lineStyle);
GUI.Box(new Rect((Screen.width-width)/2,(Screen.height-distance)/2 - length, width,length),tex,lineStyle);
GUI.Box(new Rect((Screen.width- width) /2,(Screen.height+distance)/2, width,length),tex,lineStyle);
}
}
fps_DoorControl
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 靜態(tài)滑動(dòng)門設(shè)置-1
/// </summary>
public class fps_DoorControl : MonoBehaviour {
public int doorId; //門的id號(hào)
public Vector3 from; //原始位置
public Vector3 to;//滑動(dòng)位置
public float fadeSpeed=5; //滑動(dòng)速度
public bool requireKey = false; //通過鑰匙打開
public AudioClip doorSwitchClip; //開門聲效
public AudioClip accessDeniedClip; //進(jìn)入聲效
private Transform door; //獲取門
private GameObject player; //玩家
private AudioSource audioSource; //聲效
private fps_PlayerInventory playerInventory;
private int count;
public int Count {
get { return count; }
set {
if (count == 0 && value == 1 || count == 1 && value == 0)
{
audioSource.clip = doorSwitchClip;
audioSource.Play();
}
count = value;
}
}
void Start() {
if (transform.childCount > 0)
{
door = transform.GetChild(0);
}
player = GameObject.FindGameObjectWithTag(Tags.player);
audioSource = this.GetComponent<AudioSource>();
playerInventory = player.GetComponent<fps_PlayerInventory>();
door.localPosition = from;
}
void Update() {
if (Count>0)
{
door.localPosition = Vector3.Lerp(door.localPosition, to, fadeSpeed * Time.deltaTime);
// Debug.Log("Count++" + Count);
}
else
{
door.localPosition = Vector3.Lerp(door.localPosition, from, fadeSpeed * Time.deltaTime);
}
}
/// <summary>
/// 進(jìn)入觸發(fā)器
/// </summary>
/// <param name="other"></param>
void OnTriggerEnter(Collider other) {
Debug.Log("進(jìn)入門的觸發(fā)器");
if (other.gameObject == player)
{
if (requireKey)
{
if (playerInventory.HasKey(doorId))
{
Count++;
}
else
{
audioSource.clip = accessDeniedClip;
audioSource.Play();
}
}
else
{
Count++;
}
}
else if (other.gameObject.tag == Tags.enemy && other is CapsuleCollider)
{
Count++;
}
}
/// <summary>
/// 離開觸發(fā)器
/// </summary>
void OnTriggerExit(Collider other) {
Debug.Log("離開門的觸發(fā)器");
if (other.gameObject == player||other.gameObject.tag==Tags.enemy&&other is CapsuleCollider)
{
Count = Mathf.Max(0,Count-1);
}
}
}
fps_EnemyAI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class fps_EnemyAI : MonoBehaviour {
public float patrolSpeed = 2f; //巡邏時(shí)間
public float chaseSpeed = 5f; //追擊時(shí)間
public float chaseWaitTime = 5f;
public float patrolWaitTime = 1f;
public Transform[] patrolWayPoint;//尋路點(diǎn)
private fps_EnemySight enemySight;
private NavMeshAgent nav;
private Transform player;
private fps_PlayerHealth playHealth ; //玩家血量
private float chaseTimer;
private float patrolTimer;
private int wayPointIndex;
void Start() {
enemySight = this.GetComponent<fps_EnemySight>();
nav = this.GetComponent<NavMeshAgent>();
player = GameObject.FindGameObjectWithTag(Tags.player).transform;
playHealth = player.GetComponent<fps_PlayerHealth>();
}
void Update() {
if (enemySight.playerInSight && playHealth.hp > 0)
{
Shooting();
}
else if (enemySight.playerPosition != enemySight.resetPosition && playHealth.hp > 0)
{
Chasing();
}
else
{
Patrolling();
}
}
/// <summary>
/// 設(shè)置尋路點(diǎn)
/// </summary>
private void Shooting() {
nav.SetDestination(transform.position);
}
/// <summary>
/// 追擊
/// </summary>
private void Chasing() {
Vector3 sightingDeltaPos = enemySight.playerPosition - transform.position;
if (sightingDeltaPos.sqrMagnitude > 4f)
{
nav.destination = enemySight.playerPosition;
}
nav.speed = chaseSpeed;
if (nav.remainingDistance < nav.stoppingDistance)
{
chaseTimer += Time.deltaTime;
if (chaseTimer >= chaseWaitTime)
{
enemySight.playerPosition = enemySight.resetPosition;
chaseTimer = 0;
}
}
else
{
chaseTimer = 0;
}
}
/// <summary>
/// 巡邏
/// </summary>
private void Patrolling() {
nav.speed = patrolSpeed;
if (nav.destination == enemySight.resetPosition||nav.remainingDistance<nav.stoppingDistance)
{
patrolTimer += Time.deltaTime;
if (patrolTimer>=patrolWaitTime)
{
if (wayPointIndex==patrolWayPoint.Length-1)
{
wayPointIndex = 0;
}
else
{
wayPointIndex++;
}
patrolTimer = 0;
}
}
else
{
patrolTimer = 0;
}
nav.destination = patrolWayPoint[wayPointIndex].position;
}
}
fps_EnemyAnimation
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class fps_EnemyAnimation : MonoBehaviour {
public float deadZone = 5f;
private Transform player;
private fps_EnemySight enemySight;
private NavMeshAgent nav;
private Animator anim;
private HashIDs hash;
private AnimatorSetup animSetup;
void Start() {
player = GameObject.FindGameObjectWithTag(Tags.player).transform;
enemySight = this.GetComponent<fps_EnemySight>();
nav = this.GetComponent<NavMeshAgent>();
anim = this.GetComponent<Animator>();
hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
animSetup = new AnimatorSetup(anim, hash);
nav.updateRotation = false;
anim.SetLayerWeight(1, 1f); //設(shè)置權(quán)重
anim.SetLayerWeight(2, 1f);
deadZone *= Mathf.Deg2Rad; //弧度
}
void Update() {
NavAnimSetup();
}
//動(dòng)畫內(nèi)置函數(shù)
void OnAnimatorMove() {
nav.velocity = anim.deltaPosition / Time.deltaTime;
transform.rotation = anim.rootRotation;
}
void NavAnimSetup() {
float speed;
float angle;
if (enemySight.playerInSight)
{
speed = 0;
angle = FindAngle(transform.forward,player.position-transform.position,transform.up);
}
else
{
speed = Vector3.Project(nav.desiredVelocity,transform.forward).magnitude;
angle = FindAngle(transform.forward,nav.desiredVelocity,transform.up);
if (Mathf.Abs(angle)<deadZone)
{
transform.LookAt(transform.position+nav.desiredVelocity);
angle = 0;
}
}
animSetup.Setup(speed,angle);
}
private float FindAngle(Vector3 formVector,Vector3 toVector,Vector3 upVector){
if (toVector==Vector3.zero)
return 0f;
float angle = Vector3.Angle(formVector,toVector);
Vector3 nomal = Vector3.Cross(formVector,toVector);
angle *= Mathf.Sign(Vector3.Dot(nomal,upVector));
angle *= Mathf.Deg2Rad;
return angle;
}
}
fps_EnemyHealth
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fps_EnemyHealth : MonoBehaviour {
public float hp = 100;
private Animator anim;
private HashIDs hash;
private bool isDead=false;
void Start () {
anim = this.GetComponent<Animator>();
hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
}
void Update () {
}
/// <summary>
/// 如果被槍打中的話調(diào)用此方法
/// </summary>
/// <param name="damage"></param>
public void TakeDamage(float damage) {
hp -= damage;
if (hp<=0&&!isDead)
{
isDead = true;
GetComponent<CapsuleCollider>().enabled=false;
GetComponent<fps_EnemyAnimation>().enabled=false;
GetComponent<fps_EnemyAI>().enabled=false;
GetComponent<fps_EnemySight>().enabled=false;
GetComponent<fps_EnemyShoot>().enabled=false;
GetComponent<UnityEngine.AI.NavMeshAgent>().enabled=false;
GetComponentInChildren<Light>().enabled = false;
GetComponentInChildren<LineRenderer>().enabled = false;
anim.SetBool(hash.playerInSightBool,false);
anim.SetBool(hash.deadBool,true);
//銷毀
Destroy(gameObject,2f);
}
}
}
fps_EnemyShoot
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fps_EnemyShoot : MonoBehaviour {
public float maximumDamage = 120;
public float minimumDamage=45;
public AudioClip shotClip;
public float flashIntensity = 3f; //閃爍強(qiáng)度
public float fadeSpeed = 10f;
private Animator anim;
private HashIDs hash;
private LineRenderer laserShotLine;
private Light laserShotLight; //光的特效
private SphereCollider col;
private Transform player;
private fps_PlayerHealth playerHealth; //玩家血量
private bool shooting;
private float scaleDamage;
void Start () {
anim = this.GetComponent<Animator>();
laserShotLine = this.GetComponentInChildren<LineRenderer>();
laserShotLight = laserShotLine.gameObject.GetComponent<Light>();
col = this.GetComponentInChildren<SphereCollider>();
player = GameObject.FindGameObjectWithTag(Tags.player).transform;
playerHealth = player.GetComponent<fps_PlayerHealth>();
hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
laserShotLine.enabled = false;
laserShotLight.intensity = 0;
scaleDamage = maximumDamage - minimumDamage;
}
void Update () {
float shot=anim.GetFloat(hash.shotFloat);
// Debug.Log("射擊:::"+shot);
if (shot>0.05f&&!shooting) //不斷監(jiān)聽 符合條件調(diào)用射擊的方法
{
Shoot();
}
if (shot<0.05f)
{
shooting = false;
laserShotLine.enabled = false;
}
laserShotLight.intensity = Mathf.Lerp(laserShotLight.intensity,0f,fadeSpeed*Time.deltaTime);
}
void OnAnimatorIK(int layerIndex) {
float aimWeight = anim.GetFloat(hash.aimWeightFloat);
anim.SetIKPosition(AvatarIKGoal.RightHand,player.position+Vector3.up*1.5f);
anim.SetIKPositionWeight(AvatarIKGoal.RightHand,aimWeight);
}
/// <summary>
/// 射擊
/// </summary>
public void Shoot() {
shooting = true;
float fractionalDitance = (col.radius - Vector3.Distance(transform.position, player.position)) / col.radius;
float damage = scaleDamage * fractionalDitance + minimumDamage;
playerHealth.TakeDamage(damage);
//調(diào)用槍的特效
ShotEffects();
}
/// <summary>
/// 槍的特效
/// </summary>
private void ShotEffects() {
laserShotLine.SetPosition(0,laserShotLine.transform.position);
laserShotLine.SetPosition(1,player.position+Vector3.up*1.5f); //射擊的第二個(gè)位置點(diǎn)
laserShotLine.enabled = true;
laserShotLight.intensity = flashIntensity;
// AudioSource.PlayClipAtPoint(shotClip,laserShotLight.transform.position);
AudioSource.PlayClipAtPoint(shotClip, transform.position);
}
}
fps_EnemySight
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class fps_EnemySight : MonoBehaviour {
public float fieldOfViewAngle = 110f;
public bool playerInSight;
public Vector3 playerPosition;
public Vector3 resetPosition=Vector3.zero;
private NavMeshAgent nav;
private SphereCollider col;
private Animator anim;
private GameObject player;
private fps_PlayerHealth playerHealth;
private HashIDs hash;
private fps_PlayerControl playerControl;
void Start () {
nav = this.GetComponent<NavMeshAgent>();
col = GetComponentInChildren<SphereCollider>();
anim = this.GetComponent<Animator>();
player = GameObject.FindGameObjectWithTag(Tags.player);
playerHealth = player.GetComponent<fps_PlayerHealth>();
playerControl = player.GetComponent<fps_PlayerControl>();
hash =GameObject.FindGameObjectWithTag("GameController").GetComponent<HashIDs>();
fps_GunScripts.PlayerShootEvent += ListenPlayer;
}
void Update () {
//判斷如果玩家的血量大于0
if (playerHealth.hp>0)
{
anim.SetBool(hash.playerInSightBool,playerInSight);//1205
//anim.SetBool("PlayerInSight", playerInSight); //靠近玩家范圍開始攻打
// anim.SetBool(hash.playerInSightBool, true);
}
else
{
anim.SetBool(hash.playerInSightBool,false);
}
}
void OnTriggerStay(Collider other) {
// Debug.Log("進(jìn)入視野范圍之內(nèi)");
if (other.gameObject.tag == "Player")
{
playerInSight = false;
Vector3 direction = other.transform.position - transform.position;
float angle = Vector3.Angle(direction,transform.forward);
if (angle<fieldOfViewAngle*0.5f)
{
RaycastHit hit;
if (Physics.Raycast(transform.position+transform.up,direction,out hit)) //1204
{
if (hit.collider.gameObject==player)
{
playerInSight = true;
playerPosition = player.transform.position;
// Debug.Log("進(jìn)入范圍");
}
}
}
//判斷如果玩家處于行走或者跑步狀態(tài) 哪就監(jiān)聽玩家 調(diào)用監(jiān)聽玩家的函數(shù)
if (playerControl.State==PlayerState.Walk||playerControl.State==PlayerState.Run)
{
ListenPlayer();
}
}
}
/// <summary>
/// 退出觸發(fā)器
/// </summary>
void OnTriggerExit(Collider other) {
// Debug.Log("退出視野范圍");
if (other.gameObject == player)
{
playerInSight = false;
}
}
/// <summary>
/// 監(jiān)聽玩家的方法
/// </summary>
private void ListenPlayer()
{
if (Vector3.Distance(player.transform.position,transform.position)<=col.radius)
{
playerPosition = player.transform.position;
}
}
/// <summary>
/// 銷毀時(shí)調(diào)用的函數(shù)
/// </summary>
void OnDestroy() {
//注銷監(jiān)聽的方法 -=ListenPlayer
fps_GunScripts.PlayerShootEvent -= ListenPlayer;
Debug.Log("銷毀--注銷監(jiān)聽");
}
}
fps_ExitTrigger
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 出口制作
/// </summary>
public class fps_ExitTrigger : MonoBehaviour {
public float timeToInactivePlayer=2.0f;
public float timeToRestart = 2.0f;
private GameObject player;
private bool playerInExit;
private float timer;
private FadeInOut fader;
void Start () {
player = GameObject.FindGameObjectWithTag(Tags.player);
fader = GameObject.FindGameObjectWithTag(Tags.fader).GetComponent<FadeInOut>();
}
void Update () {
if (playerInExit)
{
InExitActivation();
}
}
/// <summary>
/// 進(jìn)入出口范圍
/// </summary>
/// <param name="other"></param>
void OnTriggerEnter(Collider other) {
//Debug.Log("進(jìn)入觸發(fā)器");
if (other.gameObject==player)
{
playerInExit = true;
timer = 0;
}
}
/// <summary>
/// 離開觸發(fā)范圍
/// </summary>
void OnTriggerExit(Collider other) {
Debug.Log("退出 離開范圍");
if (other.gameObject==player)
{
playerInExit = false;
timer = 0;
}
}
/// <summary>
/// 激活出口
/// </summary>
private void InExitActivation() {
timer += Time.deltaTime;
if (timer>=timeToInactivePlayer)
{
player.GetComponent<fps_PlayerHealth>().DisableInput();
}
if (timer>=timeToRestart)
{
//fader.EndScene();
fader.NextScene();
}
}
}
fps_FPCamera
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制相機(jī)的旋轉(zhuǎn)邏輯 鼠標(biāo)和按鍵
/// </summary>
[RequireComponent(typeof(Camera))]
public class fps_FPCamera : MonoBehaviour {
public Vector2 mouseLookSensitivity = new Vector2(5,5);
public Vector2 rotationXLimit = new Vector2(87,-87);
public Vector2 rotationYLimit = new Vector2(-360,360);
public Vector3 positionOffset = new Vector3(0,2,-0.2f);
private Vector2 currentMouseLook = Vector2.zero;
private float x_Angle = 0;
private float y_Angle = 0;
private fps_PlayerParemeter paremeter;
private Transform m_Transform;
void Start () {
paremeter = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<fps_PlayerParemeter>();
m_Transform= transform;
m_Transform.localPosition = positionOffset;
}
void Update () {
UpdateInput();
}
void LateUpdate() {
Quaternion xQuaternion = Quaternion.AngleAxis(y_Angle,Vector3.up);
Quaternion yQuaternion = Quaternion.AngleAxis(0,Vector3.left);
m_Transform.parent.rotation = xQuaternion * yQuaternion;
yQuaternion = Quaternion.AngleAxis(-x_Angle,Vector3.left);
m_Transform.rotation = xQuaternion * yQuaternion;
}
private void UpdateInput() {
if (paremeter.inputSmoothLook==Vector2.zero)
{
return;
}
GetMouseLook();
y_Angle += currentMouseLook.x;
x_Angle += currentMouseLook.y;
y_Angle = y_Angle < -360 ? y_Angle += 360 : y_Angle;
y_Angle = y_Angle > 360 ? y_Angle -= 360 : y_Angle;
y_Angle = Mathf.Clamp(y_Angle,rotationYLimit.x,rotationYLimit.y);
x_Angle = x_Angle < -360 ? x_Angle += 360 : x_Angle;
x_Angle = x_Angle > 360 ? x_Angle -= 360 : x_Angle;
x_Angle = Mathf.Clamp(x_Angle, -rotationXLimit.x, -rotationXLimit.y);
}
/// <summary>
/// 鼠標(biāo)的觀看角度
/// </summary>
private void GetMouseLook() {
currentMouseLook.x = paremeter.inputSmoothLook.x;
currentMouseLook.y = paremeter.inputSmoothLook.y;
currentMouseLook.x *= mouseLookSensitivity.x;
currentMouseLook.y *= mouseLookSensitivity.y;
currentMouseLook.y *= -1;
}
}
fps_FPInput
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 玩家輸入
/// </summary>
public class fps_FPInput : MonoBehaviour {
public bool LockCursor {
get { return Cursor.lockState == CursorLockMode.Locked ? true : false; }
set {
Cursor.visible = value;
Cursor.lockState = value ? CursorLockMode.Locked : CursorLockMode.None;
}
}
private fps_PlayerParemeter paremeter;
private fps_Input input;
void Start() {
LockCursor = true;
paremeter = this.GetComponent<fps_PlayerParemeter>();
input = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<fps_Input>();
}
void Update() {
InitialInput();
}
/// <summary>
/// 監(jiān)聽輸入
/// </summary>
private void InitialInput() {
paremeter.inputMoveVector = new Vector2(input.GetAxis("Horizontal"),input.GetAxis("Vertical"));
paremeter.inputSmoothLook = new Vector2(input.GetAxisRaw("Mouse X"), input.GetAxisRaw("Mouse Y"));
paremeter.inputCrouch = input.GetButton("Crouch");
paremeter.inputJump = input.GetButton("Jump");
paremeter.inputSprint = input.GetButton("Sprint");
paremeter.inputFire = input.GetButton("Fire");
paremeter.inputReload = input.GetButton("Reload");
}
}
fps_GunScripts
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public delegate void PlayerShoot();
/// <summary>
/// 武器動(dòng)畫
/// </summary>
public class fps_GunScripts : MonoBehaviour {
public static event PlayerShoot PlayerShootEvent;
public float fireRate = 0.1f;
public float damage = 40;
public float reloadTime = 1.5f;
public float flashRate = 0.02f;
public AudioClip fireAudio;
public AudioClip reloadAudio;
public AudioClip damageAudio;
public AudioClip dryFireAudio;
public GameObject explosion;
public int bulletCount=30;
public int chargeBulletCount = 60;
public Text bulletText;
//動(dòng)畫片段名稱
private string reloadAnim = "Reload";
private string fireAnim = "Single_Shot";
private string walkAnim = "Walk";
private string runAnim = "Run";
private string jumpAnim = "Jump";
private string idledAnim = "Idle";
private Animation anim;
private float nextFireTime = 0.0f;
private MeshRenderer flash;
private int currentBullet;
private int currentChargeBullet;
private fps_PlayerParemeter paremeter;
private fps_PlayerControl playerControl;
void Start () {
paremeter = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<fps_PlayerParemeter>();
playerControl = GameObject.FindGameObjectWithTag(Tags.player).GetComponent<fps_PlayerControl>();
anim = this.GetComponent<Animation>();
// flash = this.transform.FindChild("muzzle_flash").GetComponent<MeshRenderer>();
flash = this.transform.Find("muzzle_flash").GetComponent<MeshRenderer>();
flash.enabled = false;
currentBullet = bulletCount;
currentChargeBullet = chargeBulletCount;
bulletText.text = currentBullet + "/" + currentChargeBullet;
}
void Update () {
if (paremeter.inputReload&¤tBullet<bulletCount)
{
Reload();
}
else if (paremeter.inputFire&&!anim.IsPlaying(reloadAnim))
{
Fire();
}
else if (!anim.IsPlaying(reloadAnim))
{
StateAnim(playerControl.State);
}
}
/// <summary>
/// 換槍動(dòng)畫
/// </summary>
private void ReloadAnim() {
anim.Stop(reloadAnim);
anim[reloadAnim].speed = (anim[reloadAnim].clip.length/reloadTime);
anim.Rewind(reloadAnim);
anim.Play(reloadAnim);
}
private IEnumerator ReloadFinish() {
yield return new WaitForSeconds(reloadTime);
if (currentChargeBullet>=bulletCount-currentBullet)
{
currentChargeBullet -= (bulletCount-currentBullet);
currentBullet = bulletCount;
}
else
{
currentBullet += currentChargeBullet;
currentChargeBullet = 0;
}
bulletText.text = currentBullet + "/" + currentChargeBullet;
}
/// <summary>
/// 重裝子彈
/// </summary>
private void Reload() {
if (!anim.IsPlaying(reloadAnim))
{
if (currentChargeBullet>0)
{
StartCoroutine(ReloadFinish());
}
else
{
anim.Rewind(fireAnim);
anim.Play(fireAnim);
AudioSource.PlayClipAtPoint(dryFireAudio,transform.position);
return;
}
AudioSource.PlayClipAtPoint(reloadAudio,transform.position);
ReloadAnim();
}
}
/// <summary>
/// 開火特效
/// </summary>
/// <returns></returns>
private IEnumerator Flash() {
flash.enabled = true;
yield return new WaitForSeconds(flashRate);
flash.enabled = false;
}
/// <summary>
/// 射擊
/// </summary>
private void Fire() {
if (Time.time>nextFireTime)
{
if (currentBullet<=0)
{
Reload();
nextFireTime = Time.time + fireRate;
return;
}
currentBullet--;
bulletText.text = currentBullet + "/" + currentChargeBullet;
DamageEnemy();
if (PlayerShootEvent!=null)
{
PlayerShootEvent();
}
AudioSource.PlayClipAtPoint(fireAudio,transform.position);
nextFireTime = Time.time + fireRate;
anim.Rewind(fireAnim);
anim.Play(fireAnim);
StartCoroutine(Flash());
}
}
/// <summary>
/// 敵人收到攻擊
/// </summary>
private void DamageEnemy() {
Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));
RaycastHit hit;
if (Physics.Raycast(ray,out hit))
{
if (hit.transform.tag==Tags.enemy&&hit.collider is CapsuleCollider) //機(jī)器人
{
AudioSource.PlayClipAtPoint(damageAudio,hit.transform.position);
GameObject go = Instantiate(explosion,hit.point,Quaternion.identity);
Destroy(go,3f);
hit.transform.GetComponent<fps_EnemyHealth>().TakeDamage(damage);
}else if (hit.transform.tag == Tags.buzzer ) //無(wú)人機(jī)
{
AudioSource.PlayClipAtPoint(damageAudio, hit.transform.position);
GameObject go = Instantiate(explosion, hit.point, Quaternion.identity);
Destroy(go, 3f);
hit.transform.GetComponent<fps_BuzzerHealth>().TakeDamage(damage);
}
else if (hit.transform.tag == Tags.spider) //無(wú)人機(jī)
{
AudioSource.PlayClipAtPoint(damageAudio, hit.transform.position);
GameObject go = Instantiate(explosion, hit.point, Quaternion.identity);
Destroy(go, 3f);
hit.transform.GetComponent<fps_SpiderHealth>().TakeDamage(damage);
}
}
}
/// <summary>
/// 動(dòng)畫狀態(tài)控制
/// </summary>
/// <param name="animName"></param>
private void PlayerStateAnim(string animName) {
if (!anim.IsPlaying(animName))
{
anim.Rewind(animName);
anim.Play(animName);
}
}
/// <summary>
/// 動(dòng)畫狀態(tài)
/// </summary>
/// <param name="state"></param>
private void StateAnim(PlayerState state) {
switch (state)
{
case PlayerState.Idle:
PlayerStateAnim(idledAnim);
break;
case PlayerState.Walk:
PlayerStateAnim(walkAnim);
break;
case PlayerState.Coruch:
PlayerStateAnim(walkAnim);
break;
case PlayerState.Run:
PlayerStateAnim(runAnim);
break;
}
}
}
fps_Input
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 輸入按鍵控制控制
/// </summary>
public class fps_Input : MonoBehaviour {
public class fps_InputAxis {
public KeyCode positive;
public KeyCode negative;
}
//字典 鍵值對(duì) 按鍵 鼠標(biāo) 水平 垂直
public Dictionary<string, KeyCode> buttons = new Dictionary<string, KeyCode>();
public Dictionary<string, fps_InputAxis> axis = new Dictionary<string, fps_InputAxis>();
public List<string> unityAxis = new List<string>();
//執(zhí)行配置
void Start() {
SetupDefaults();
}
/// <summary>
/// 按鍵配置
/// </summary>
/// <param name="type"></param>
private void SetupDefaults(string type ="") {
if (type==""||type=="buttons")
{
if (buttons.Count==0)
{
AddButton("Fire",KeyCode.Mouse0);
AddButton("Reload",KeyCode.R);
AddButton("Jump",KeyCode.Space);
AddButton("Crouch",KeyCode.C);
AddButton("Sprint",KeyCode.LeftShift);
}
}
if (type == "" || type == "Axis")
{
if (axis.Count == 0)
{
AddAxis("Horizontal", KeyCode.W,KeyCode.S);
AddAxis("Vertical", KeyCode.A,KeyCode.D);
}
}
if (type == "" || type == "UnityAxis")
{
if (unityAxis.Count == 0)
{
AddUnityAxis("Mouse X");
AddUnityAxis("Mouse Y");
AddUnityAxis("Horizontal");
AddUnityAxis("Vertical");
}
}
}
private void AddButton(string n,KeyCode k) {
if (buttons.ContainsKey(n))
{
buttons[n] = k;
}
else
{
buttons.Add(n,k);
}
}
private void AddAxis(string n,KeyCode pk,KeyCode nk) {
if (axis.ContainsKey(n))
{
axis[n] = new fps_InputAxis() { positive=pk,negative=nk};
}
else
{
axis.Add(n,new fps_InputAxis() { positive = pk, negative = nk });
}
}
private void AddUnityAxis(string n) {
if (!unityAxis.Contains(n))
{
unityAxis.Add(n);
}
}
/// <summary>
/// 判斷是否有按鍵輸入
/// </summary>
/// <returns></returns>
public bool GetButton(string button) {
if (buttons.ContainsKey(button))
{
return Input.GetKey(buttons[button]);
}
return false;
}
/// <summary>
/// 是否有按下
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
public bool GetButtonDown(string button)
{
if (buttons.ContainsKey(button))
{
return Input.GetKeyDown(buttons[button]);
}
return false;
}
/// <summary>
/// 是否有值輸入
/// </summary>
/// <param name="axis"></param>
/// <returns></returns>
public float GetAxis(string axis) {
if (this.unityAxis.Contains(axis))
{
return Input.GetAxis(axis);
}
return 0;
}
public float GetAxisRaw(string axis) {
if (this.axis.ContainsKey(axis))
{
float val = 0;
if (Input.GetKey(this.axis[axis].positive))
{
return 1;
}
if (Input.GetKey(this.axis[axis].negative))
{
return -1;
}
return val;
}
else if (unityAxis.Contains(axis))
{
return Input.GetAxisRaw(axis);
}
else
{
return 0;
}
}
}
fps_KeyPickUp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 鑰匙卡
/// </summary>
public class fps_KeyPickUp : MonoBehaviour {
public AudioClip keyGrab;
public int keyId;
private GameObject player;
private fps_PlayerInventory playerInventory;
void Start () {
player = GameObject.FindGameObjectWithTag(Tags.player);
playerInventory = player.GetComponent<fps_PlayerInventory>();
}
void Update () {
}
/// <summary>
/// 進(jìn)入觸發(fā)范圍
/// </summary>
/// <param name="other"></param>
void OnTriggerEnter(Collider other) {
Debug.Log("進(jìn)入鑰匙觸發(fā)范圍--準(zhǔn)備執(zhí)起鑰匙卡");
if (other.gameObject==player)
{
AudioSource.PlayClipAtPoint(keyGrab,transform.position); //播放執(zhí)起聲效
playerInventory.AddKey(keyId); //設(shè)置的id號(hào)對(duì)應(yīng) 鑰匙 跟 門 是配對(duì)
Destroy(this.gameObject);
}
}
}
fps_LaserDamage
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 激光墻
/// </summary>
public class fps_LaserDamage : MonoBehaviour {
public int damage = 30;
public float damageDelay = 1; //1秒傷害1次
private float lastDamageTime = 0;
private GameObject player;
void Start () {
player = GameObject.FindGameObjectWithTag(Tags.player); //獲取玩家的引用
}
void Update () {
}
/// <summary>
/// 觸發(fā)器逗留
/// </summary>
void OnTriggerStay(Collider other) {
// Debug.Log("進(jìn)入激光墻觸發(fā)");
if (other.gameObject==player&&Time.time>lastDamageTime+damageDelay)
{
player.GetComponent<fps_PlayerHealth>().TakeDamage(damage); //執(zhí)行玩家受傷害的方法
lastDamageTime = Time.time; //確認(rèn)當(dāng)前時(shí)間
}
}
}
fps_PlayerControl
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 玩家4種狀態(tài)
/// </summary>
public enum PlayerState
{
None,
Idle,
Walk,
Coruch,
Run,
}
/// <summary>
/// 玩家控制
/// </summary>
public class fps_PlayerControl : MonoBehaviour {
private PlayerState state = PlayerState.None;
public PlayerState State {
get {
if (running)
state = PlayerState.Run;
else if (walking)
state = PlayerState.Walk;
else if (crouching)
state = PlayerState.Coruch;
else
state = PlayerState.Idle;
return state;
}
}
public float sprintSpeed = 10.0f;
public float sprintJumpSpeed = 8.0f;
public float normalSpeed = 6.0f;
public float normalJumpSpeed = 7.0f;
public float crouchSpeed = 2.0f;
public float crouchJumpSpeed = 5.0f;
public float crouchDeltaHeight = 0.5f;
public float gravity = 20.0f;
public float cameraMoveSpeed = 8.0f;
public AudioClip jumpAudio;
private float speed;
private float jumpSpeed;
private Transform mainCamera;
private float standardCamHeight;
private float crouchingCamHeight;
private bool grounded = false;
private bool walking = false;
private bool crouching = false;
private bool stopCrouching = false;
private bool running = false;
private Vector3 normalControllerCenter = Vector3.zero;
private float normalControllerHeight = 0.0f;
private float timer = 0;
private CharacterController controller;
private AudioSource audioSource;
private fps_PlayerParemeter paremeter;
private Vector3 moveDirection = Vector3.zero;
void Start() {
crouching = false;
walking = false;
running = false;
speed = normalSpeed;
jumpSpeed = normalJumpSpeed;
mainCamera = GameObject.FindGameObjectWithTag(Tags.mainCamera).transform;
standardCamHeight = mainCamera.localPosition.y;
crouchingCamHeight = standardCamHeight - crouchDeltaHeight;
audioSource = this.GetComponent<AudioSource>();
controller = this.GetComponent<CharacterController>();
paremeter = this.GetComponent<fps_PlayerParemeter>();
normalControllerCenter = controller.center;
normalControllerHeight = controller.height;
}
void FixedUpdate() {
UpdateMove();
AudioManager();
}
/// <summary>
/// 更新有移動(dòng)
/// </summary>
void UpdateMove(){
if (grounded)
{
moveDirection = new Vector3(paremeter.inputMoveVector.x, 0, paremeter.inputMoveVector.y);
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (paremeter.inputJump)
{
moveDirection.y = jumpSpeed;
AudioSource.PlayClipAtPoint(jumpAudio, transform.position);
CurrentSpeed();
}
}
moveDirection.y -= gravity * Time.deltaTime;
CollisionFlags flags = controller.Move(moveDirection*Time.deltaTime);
grounded = (flags&CollisionFlags.CollidedBelow) != 0;
if (Mathf.Abs(moveDirection.x)>0&&grounded||Mathf.Abs(moveDirection.z)>0&&grounded)
{
if (paremeter.inputSprint)
{
walking = false;
running = true;
crouching = false;
}
else if (paremeter.inputCrouch)
{
walking = false;
running = false;
crouching = true;
}
else
{
walking = true ;
running = false;
crouching = false;
}
}
else
{
if (walking)
walking = false;
if (running)
running = false;
if (paremeter.inputCrouch)
crouching = true;
else
crouching = false;
}
if (crouching)
{
controller.height = normalControllerHeight - crouchDeltaHeight;
controller.center = normalControllerCenter - new Vector3(0, crouchDeltaHeight/2,0);
}
else
{
controller.height = normalControllerHeight ;
controller.center = normalControllerCenter;
}
UpdateCrouch();
CurrentSpeed();
}
/// <summary>
/// 玩家當(dāng)前速度管理
/// </summary>
private void CurrentSpeed() {
switch (State)
{
case PlayerState.Idle:
speed = normalSpeed;
jumpSpeed = normalJumpSpeed;
break;
case PlayerState.Walk:
speed = normalSpeed;
jumpSpeed = normalJumpSpeed;
break;
case PlayerState.Coruch:
speed = crouchSpeed;
jumpSpeed = crouchJumpSpeed;
break;
case PlayerState.Run:
speed = sprintSpeed;
jumpSpeed = sprintJumpSpeed;
break;
}
}
/// <summary>
/// 聲效管理器
/// </summary>
private void AudioManager() {
if (State == PlayerState.Walk)
{
audioSource.pitch = 1.0f;
if (!audioSource.isPlaying)
{
audioSource.Play();
}
}
else if (State == PlayerState.Run)
{
audioSource.pitch = 1.3f;
if (!audioSource.isPlaying)
{
audioSource.Play();
}
}
else
audioSource.Stop();
}
/// <summary>
/// 更新蹲伏狀態(tài)
/// </summary>
private void UpdateCrouch() {
if (crouching)
{
if (mainCamera.localPosition.y > crouchingCamHeight)
{
if (mainCamera.localPosition.y - (crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed) < crouchingCamHeight)
mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, crouchingCamHeight, mainCamera.localPosition.z);
else
mainCamera.localPosition -= new Vector3(0, crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed, 0);
}
else
mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, crouchingCamHeight, mainCamera.localPosition.z);
}
else
{
if (mainCamera.localPosition.y < standardCamHeight)
{
if (mainCamera.localPosition.y + (crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed) > standardCamHeight)
mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, standardCamHeight, mainCamera.localPosition.z);
else
mainCamera.localPosition += new Vector3(0, crouchDeltaHeight * Time.deltaTime * cameraMoveSpeed, 0);
}
else
mainCamera.localPosition = new Vector3(mainCamera.localPosition.x, standardCamHeight, mainCamera.localPosition.z);
}
}
}
fps_PlayerHealth
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.ImageEffects;
/// <summary>
/// 玩家生命值
/// </summary>
public class fps_PlayerHealth : MonoBehaviour {
public bool isDead;
public float resetAfterDeathTime = 0;
public AudioClip deadClip;
public AudioClip damageClip;
public float maxHP = 100;
public float hp = 100;
public float recoverSpeed = 1;
private float timer = 0;
private FadeInOut fader;
private ColorCorrectionCurves colorCurves; //屏幕特效
void Start () {
hp = maxHP;
fader = GameObject.FindGameObjectWithTag(Tags.fader).GetComponent<FadeInOut>();
colorCurves = GameObject.FindGameObjectWithTag(Tags.mainCamera).GetComponent<ColorCorrectionCurves>();
BleedBehavior.BloodAmount = 0; //設(shè)置為0 沒有顯示紅色的區(qū)域
}
void Update () {
if (!isDead)
{
hp += recoverSpeed * Time.deltaTime; //恢復(fù)時(shí)間
if (hp>maxHP)
{
hp = maxHP;
}
}
if (hp<0)
{
if (!isDead)
{
PlayerDead();
}
else
{
LevelReset();
}
}
}
/// <summary>
/// 玩家受到攻擊
/// </summary>
public void TakeDamage(float damage) {
if (isDead)
{
return;
}
AudioSource.PlayClipAtPoint(damageClip,transform.position);
float damage01 = damage;
if (damage01<40)
{
damage01 *= 30;
}
//BleedBehavior.BloodAmount += Mathf.Clamp01(damage/hp);
BleedBehavior.BloodAmount += Mathf.Clamp01(damage01 / hp);
hp -= damage;
}
/// <summary>
/// 不能繼續(xù)輸入
/// </summary>
public void DisableInput() {
transform.Find("FP_Camera/Weapon_Camera").gameObject.SetActive(false);
this.GetComponent<AudioSource>().enabled = false;
this.GetComponent<fps_PlayerControl>().enabled = false;
this.GetComponent<fps_FPInput>().enabled = false;
if (GameObject.Find("Canvas") !=null) //注意畫布的隱藏和顯示
{
GameObject.Find("Canvas").SetActive (false);
}
colorCurves.gameObject.GetComponent<fps_FPCamera>().enabled = false;
}
/// <summary>
/// 玩家掛掉
/// </summary>
public void PlayerDead() {
isDead = true;
colorCurves.enabled = true;
DisableInput();
AudioSource.PlayClipAtPoint(deadClip,transform.position);
}
/// <summary>
/// 重置
/// </summary>
public void LevelReset() {
timer += Time.deltaTime;
colorCurves.saturation -= (Time.deltaTime / 2);
colorCurves.saturation = Mathf.Max(0,colorCurves.saturation);
if (timer>=resetAfterDeathTime)
{
fader.EndScene(); //播放漸暗的效果
}
}
}
fps_PlayerInventory
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 控制id號(hào)
/// </summary>
public class fps_PlayerInventory : MonoBehaviour {
private List<int> keyArr;
void Start () {
keyArr = new List<int>();
}
void Update () {
}
/// <summary>
/// 加入Id號(hào)
/// </summary>
/// <param name="keyId"></param>
public void AddKey(int keyId) {
if (!keyArr.Contains(keyId))
{
keyArr.Add(keyId);
}
}
/// <summary>
/// 對(duì)應(yīng)門ID號(hào)確認(rèn)是否可以打開
/// </summary>
/// <param name="doorId"></param>
/// <returns></returns>
public bool HasKey(int doorId) {
if (keyArr.Contains(doorId))
{
return true;
}
return false;
}
}
fps_PlayerParemeter
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 玩家輸入?yún)?shù)的封裝
/// </summary>
[RequireComponent(typeof(CharacterController))]
public class fps_PlayerParemeter : MonoBehaviour {
[HideInInspector]
public Vector2 inputSmoothLook;
[HideInInspector]
public Vector2 inputMoveVector;
[HideInInspector]
public bool inputCrouch;
[HideInInspector]
public bool inputJump;
[HideInInspector]
public bool inputSprint;
[HideInInspector]
public bool inputFire;
[HideInInspector]
public bool inputReload;
void Start () {
}
void Update () {
}
}
HashIDs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 動(dòng)畫哈希值
/// </summary>
public class HashIDs : MonoBehaviour {
public int deadBool;
public int speedFloat;
public int playerInSightBool;
public int shotFloat;
public int aimWeightFloat;
public int angularSpeedFloat;
void Awake() {
deadBool = Animator.StringToHash("Dead");
speedFloat = Animator.StringToHash("Speed");
playerInSightBool = Animator.StringToHash("PlayerInSight");
shotFloat = Animator.StringToHash("Shot");
aimWeightFloat = Animator.StringToHash("AimWeight");
angularSpeedFloat = Animator.StringToHash("AngularSpeed");
}
void Start () {
}
void Update () {
}
}
Outdoor
BuzzerAttack
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 無(wú)人機(jī)攻擊腳本
/// </summary>
public class BuzzerAttack : MonoBehaviour
{
public LineRenderer electricArc;//攻擊閃電特效
public float coldTime = 1.0f;
public BuzzerMove move;
public float damage=40;//攻擊力
private Transform player;
private Vector3 zapNoise = Vector3.zero;
private AudioSource audioSource;
private float rechargeTimer ; //間隔計(jì)時(shí)器 冷卻時(shí)間
private bool canAttack = false; //是否到達(dá)攻擊范圍
private fps_PlayerHealth playerHealth;
void Awake()
{
player = GameObject.FindGameObjectWithTag(Tags.player).transform;
playerHealth = player.GetComponent<fps_PlayerHealth>();
audioSource = GetComponent<AudioSource>();
rechargeTimer = coldTime;
}
void Update()
{
move.moveTarget = player.position;
//Vector3.Distance(transform.position, player.position);
Vector3 dir = player.position - transform.position;
// canAttack = dir.magnitude < 2.0f; //布爾值賦值
canAttack = false;
if (dir.magnitude < 3.8f)
{
canAttack = true;
move.moveTarget = Vector3.zero; //注意位置信息1213
}
rechargeTimer -= Time.deltaTime; //冷卻中
if (rechargeTimer < 0&&canAttack)
{
zapNoise = new Vector3(Random.Range(-1.0f, 1.0f), 0.0f, Random.Range(-1.0f, 1.0f)) * 0.5f;
StartCoroutine(DoElectricArc());
// rechargeTimer = coldTime;
rechargeTimer = Random.Range(1.0f,2.0f); //重置冷卻時(shí)間
playerHealth.TakeDamage(damage);//玩家受到攻擊
}
}
/// <summary>
/// 開啟雷電攻擊功能
/// </summary>
/// <returns></returns>
IEnumerator DoElectricArc()
{
if (electricArc.enabled)
{
yield return 0;
}
//播放閃電音效
audioSource.Play();
electricArc.enabled = true;
zapNoise = transform.rotation * zapNoise;
float stopTime = Time.time + 0.2f;
while (Time.time < stopTime)
{
electricArc.SetPosition(0, electricArc.transform.position);
electricArc.SetPosition(1, player.position + zapNoise);
yield return 0;
}
electricArc.enabled = false;
}
}
BuzzerMove
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 無(wú)人機(jī)移動(dòng)
/// </summary>
public class BuzzerMove : MonoBehaviour {
public float flyingSpeed = 5.0f; //飛行速度
public float zigZagness = 3.0f; //范圍
public float zigZagSpeed = 2.5f;//速度
public float backtrackIntensity = 0.5f; //回退系數(shù)
public float oriantationMultiplier = 2.5f; //旋轉(zhuǎn)系數(shù)
public Vector3 moveTarget; //追蹤目標(biāo)
private Transform player;
private Rigidbody rigi;
private Vector3 smoothDirection = Vector3.zero; //使移動(dòng)更平滑
void Awake() {
player = GameObject.FindGameObjectWithTag("Player").transform;
rigi = transform.GetComponent<Rigidbody>();
}
void FixedUpdate () {
//Vector3 direction = player.position - transform.position;
Vector3 direction = moveTarget - transform.position;
direction.Normalize(); //平滑歸零 避免越來(lái)越大
smoothDirection = Vector3.Lerp(smoothDirection,direction,Time.deltaTime*3.0f);
Vector3 zigzag = transform.right * (Mathf.PingPong(Time.time* zigZagSpeed, 2.0f)-1.0f)* zigZagness;
float orientationSpeed = 1.0f;
Vector3 deltaVelocity = (smoothDirection * flyingSpeed+zigzag)- rigi.velocity;
if (Vector3.Dot(direction,transform.forward)>0.8f)
{
rigi.AddForce(deltaVelocity, ForceMode.Force);
}
else
{
rigi.AddForce(-deltaVelocity*backtrackIntensity, ForceMode.Force);
orientationSpeed = oriantationMultiplier;
}
float rotationAngle = AngleAroundAxis(transform.forward,direction,Vector3.up);
rigi.angularVelocity = Vector3.up * rotationAngle * 0.2f*orientationSpeed;
}
/// <summary>
/// 旋轉(zhuǎn)角度
/// </summary>
/// <returns></returns>
static float AngleAroundAxis(Vector3 dirA,Vector3 dirB, Vector3 axis) {
dirA = dirA - Vector3.Project(dirA,axis);
dirB = dirB - Vector3.Project(dirB,axis);
float angle=Vector3.Angle(dirA,dirB);
return angle * (Vector3.Dot(axis,Vector3.Cross(dirA,dirB))<0?-1:1);
}
}
fps_BuzzerHealth
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fps_BuzzerHealth : MonoBehaviour {
public float hp = 100;
public GameObject explosion;
private bool isDead = false;
/// <summary>
/// 無(wú)人機(jī)受到攻擊
/// </summary>
public void TakeDamage(float damage) {
hp -= damage;
if (hp<=0&&!isDead)
{
isDead = true;
transform.GetComponent<BuzzerMove>().enabled = false;
transform.GetComponent<BuzzerAttack>().enabled = false;
transform.GetComponent<fps_BuzzerHealth>().enabled = false;
GameObject go = Instantiate(explosion, transform.position, Quaternion.identity);
Destroy(go, 2f);
Destroy(gameObject);
}
}
}
fps_BuzzerSight
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class fps_BuzzerSight : MonoBehaviour {
void Start () {
transform.GetComponent<BuzzerMove>().enabled = false;
transform.GetComponent<BuzzerAttack>().enabled = false;
transform.GetComponent<fps_BuzzerHealth>().enabled = false;
}
/// <summary>
/// 進(jìn)入視野范圍
/// </summary>
void OnTriggerEnter(Collider collider) {
Debug.Log("進(jìn)入無(wú)人機(jī)視野范圍");
if (collider.gameObject.tag==Tags.player)
{
transform.GetComponent<BuzzerMove>().enabled = true;
transform.GetComponent<BuzzerAttack>().enabled = true;
transform.GetComponent<fps_BuzzerHealth>().enabled = true;
}
}
}
SpiderAttack
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpiderAttack : MonoBehaviour
{
public GameObject bot; //子物體
public GameObject explosionPrefab;//爆炸預(yù)制體
public float damageRadius = 5.0f; //破壞范圍
public SpiderMove move;
public float damage = 40;//攻擊力
public Transform player;
private bool canAttack = false;
private Animation anim;
private fps_PlayerHealth playerHealth;
void Awake()
{
player = GameObject.FindGameObjectWithTag(Tags.player).transform;
playerHealth = player.GetComponent<fps_PlayerHealth>();
anim = bot.GetComponent<Animation>();
}
void Start()
{
}
void Update()
{
Vector3 playerDirection = (player.position - transform.position);
float playerDis = playerDirection.magnitude;
playerDirection /= playerDis;
Vector3 dir = player.position - transform.position;
// canAttack = false;
//達(dá)到指定距離后就不在播放動(dòng)畫 1213
if (dir.magnitude < 2.0f)
{
// canAttack = true;
move.moveDirection = Vector3.zero;
anim.Stop();
StartCoroutine(Explode());
}
else
{
move.moveDirection = playerDirection;
anim.Play("forward");
}
//anim.Play("forward");
}
/// <summary>
/// 爆炸
/// </summary>
IEnumerator Explode()
{
yield return new WaitForSeconds(1f);
float damageFraction = 1 - (Vector3.Distance(player.position,transform.position)/damageRadius);
// player.GetComponent<Rigidbody>().AddExplosionForce(10,transform.position,damageRadius,0.0f,ForceMode.Impulse);
playerHealth.TakeDamage(damage);//玩家受到攻擊
GameObject go=Instantiate(explosionPrefab,transform.position,Quaternion.identity);
Destroy(go,2f);
Destroy(gameObject);
}
}
SpiderMove
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpiderMove : MonoBehaviour {
public float walkingSpeed = 5.0f; //移動(dòng)速度
[HideInInspector]
public Vector3 moveDirection; //移動(dòng)方向
[HideInInspector]
public Vector3 facingDirection; //面向方向
private Transform player; //玩家
private Rigidbody rigi;
private float orientationSpeed = 0.3f;
void Awake(){
player = GameObject.FindGameObjectWithTag(Tags.player).transform;
rigi = this.GetComponent<Rigidbody>();
}
void Start () {
}
/// <summary>
/// 追蹤玩家
/// </summary>
void FixedUpdate () {
Vector3 targetVeloctiy = moveDirection;// (player.position-transform.position) ;
// targetVeloctiy.Normalize();
Vector3 detalVeloctiy = targetVeloctiy * walkingSpeed - rigi.velocity;
rigi.AddForce(detalVeloctiy,ForceMode.Acceleration);
Vector3 faceDir = targetVeloctiy;
if (faceDir==Vector3.zero)
{
rigi.angularVelocity = Vector3.zero;
}
else
{
float rotationAngle = AngleAroundAxis(transform.forward, faceDir, Vector3.up);
rigi.angularVelocity = Vector3.up * rotationAngle * 0.2f * orientationSpeed;
}
}
/// <summary>
/// 旋轉(zhuǎn)角度
/// </summary>
/// <returns></returns>
static float AngleAroundAxis(Vector3 dirA, Vector3 dirB, Vector3 axis)
{
dirA = dirA - Vector3.Project(dirA, axis);
dirB = dirB - Vector3.Project(dirB, axis);
float angle = Vector3.Angle(dirA, dirB);
return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
}
}