一.修改枪
1.修改配置
hierarchy player/gun/gunbarrelEnd
inspector linerenderer 打勾
hierarchy player/gun/gunbarrelEnd/gunparticle
light 打勾
2.写脚本
角色射击的脚本 PlayerShoot
using UnityEngine;
using System.Collections;
public class PlayerShoot : MonoBehaviour {
//计时器
private float timer = 0;
private Light shootLight;
private ParticleSystem particleSystem;
private AudioClip shootSound;
private AudioSource audio;
private LineRenderer lin;
// Use this for initialization
void Start () {
//光源
shootLight = GameObject.Find("GunParticles").GetComponent<Light>();
//粒子特效
particleSystem = GameObject.Find("GunParticles").GetComponent<ParticleSystem>();
//原素材没有,添加组件
audio = gameObject.AddComponent<AudioSource>();
audio.clip = shootSound;
lin = transform.GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update () {
timer += Time.deltaTime;
if (Input.GetMouseButtonDown(0)&&timer>=0.5f)
{
shootLight.enabled = true;
particleSystem.Play();
audio.Play();
StartCoroutine(clearEffect());
ShootRay();
}
}
//清除开枪的特效
IEnumerator clearEffect()
{
yield return new WaitForSeconds(0.03f);
shootLight.enabled = false;
lin.enabled = false;
}
void ShootRay()
{
lin.enabled = true;
//设置起点位置0
lin.SetPosition(0, this.transform.position);
Ray r = new Ray(this.transform.position,transform.forward);
RaycastHit colliderHit;
//如果碰到障碍物
if (Physics.Raycast(r,out colliderHit))
{
//记录终点位置1
lin.SetPosition(1, colliderHit.point);
}
else //如果没碰到,就向前延伸
{
lin.SetPosition(1, transform.position + transform.forward * 20);
}
}
}
脚本拉到
hierarchy player/gun/gunbarrelEnd
二 生命值和受伤害
统一管理生命值和受伤情况的脚本,虚类脚本 HealthAndDamage
using UnityEngine;
using System.Collections;
public class HealthAndDamage : MonoBehaviour {
private float hp = 100;
private float attack = 10;
//玩家的动作控制器
protected Animator playerAni;
//受到伤害的声音
protected AudioSource audio;
//受到攻击变红
protected SkinnedMeshRenderer skin;
//受到伤害的声音
public AudioClip hurtClip;
//死亡的声音
public AudioClip deathClip;
protected virtual void Awake(0)
{
playerAni = transform.GetComponent<Animator>();
audio = gameObject.AddComponent<AudioSource>();
audio.clip = hurtClip;
}
protected virtual void Update()
{
skin.material.color = Color.Lerp(skin.material.color, Color.white, 0.01f);
}
public void GetHurt(int damage)
{
hp -= damage;
skin.material.color = Color.red;
if (hp<=0)
{
playerAni.SetTrigger("Death");
audio.clip = deathClip;
}
audio.Play();
}
protected virtual void Death()
{
}
}
角色生命值和受伤管理脚本 PlayerHealthAndDamage
using UnityEngine;
using System.Collections;
public class PlayerHealthAndDamage : HealthAndDamage {
protected override void Awake()
{
base.Awake();
attack = 70;
}
void Start()
{
hp = 100;
attack = 35;
skin = GameTool.FindTheChild(gameObject, "Player").GetComponent<SkinnedMeshRenderer>();
}
void FixedUpdate()
{
//右键一下扣20点血
if (Input.GetMouseButtonDown(1))
{
transform.GetComponent<HealthAndDamage>().GetHurt(20);
}
}
protected override void Death()
{
base.Death();
gameObject.GetComponent<PlayerMove>().enabled = false;
gameObject.GetComponent<PlayerHealthAndDamage>().enabled = false;
GameTool.FindTheChild(gameObject, "GunBarrelEnd").GetComponent<PlayerShoot>().enabled = false;
//UIManager.Instance.ShowUI(E_UiId.ExitUI);
}
}
将脚本拉到
hierarchy player
加载脚本后,将
assets/audio/Effect
里面的hurt 和death 文件拉到 已经挂载的PlayerHealthAndDamage脚本上
三 添加怪物模型
3.1加入模型
将asset/model/zombear 拉进hierarchy中
3.2添加动画控制器
1.步骤与之前角色的控制器完全一致
2.由于zombear的动画不足,从model/zombunny 文件夹中拉入idle,death,move
3.3添加component
1.capsule collider 碰撞器
2.Nav math agent 自动导航
3.4 添加导航
1.烘焙地面
上方windows按键-》Navigation-》左侧栏inspector-》Bake-》点击Bake按钮
界面变为蓝色
3.5添加脚本
EnemyMove实现敌人追逐角色,自动攻击的功能
using UnityEngine;
using System.Collections;
public class EnemyMove : MonoBehaviour {
//动画控制器
private Animator enemyAni;
//自动导航
private NavMeshAgent enemyNav;
//自动导航目标
private GameObject player;
//速度
private float speed=1;
private float timer;
//攻击力
private int attack=10;
// Use this for initialization
void Start () {
enemyAni = transform.GetComponent<Animator>();
enemyNav = transform.GetComponent<NavMeshAgent>();
//player 只有一个用标签找会快些
player = GameObject.FindGameObjectWithTag("Player");
//老方法player = GameObject.Find("Player");
}
// Update is called once per frame
void FixedUpdate () {
Move();
}
void Move()
{
if (player.GetComponent<HealthAndDamage>().hp >= 0)
{
if (Vector3.Distance(transform.position, player.transform.position) > 1.5f)
{
enemyNav.Resume();
enemyNav.SetDestination(player.transform.position);
enemyNav.speed = speed;
enemyAni.SetBool("Walking", true);
}
else
{
timer += Time.deltaTime;
enemyNav.Stop();
enemyAni.SetBool("Walking", false);
if (timer >= 2f)
{
timer = 0;
player.GetComponent<HealthAndDamage>().GetHurt(attack);
}
}
}
}
}
四 怪物生命值,收到伤害,死亡
1.怪物动画 event
点击 model/characters/Zombunny/death
右侧 找到event 打开
进度条上面有一个白色的粉笔
双击进入,里面的fuction 名为 EnemyDeath
我们需要写一个C#脚本函数,名字与fuction 名一致
EnemyHealthAndDamage
using UnityEngine;
using System.Collections;
public class EnemyHealthAndDamage : HealthAndDamage {
protected override void Awake()
{
base.Awake();
hp = 100;
attack = 10;
}
void Start()
{
hp = 100;
attack = 35;
skin = transform.Find("ZomBear").GetComponent<SkinnedMeshRenderer>();
}
protected override void Update()
{
base.Update();
if (GameObject.FindGameObjectWithTag("Player").GetComponent<HealthAndDamage>().hp <= 0)
{
this.GetComponent<NavMeshAgent>().Stop();
//获取脚本,并关闭导航
//以下两种写法也行
//this.GetComponent<NavMeshAgent>().Stop();
//this.transform.GetComponent<NavMeshAgent>().Stop();
this.GetComponent<Animator>().SetBool("Walking", false);
//获取脚本,并把Walking参数设置为false
}
}
protected override void Death()
{
base.Death();
this.GetComponent<NavMeshAgent>().Stop();
this.GetComponent<EnemyMove>().enabled = false;
//关闭碰撞箱子
this.GetComponent<CapsuleCollider>().enabled = false;
}
void EnemyDeath()
{
Destroy(this.gameObject, 3f);
}
}
为了给敌人造成伤害,修改playershoot
代码中使用使用了找tag的方式定位敌人,所以要给enemy加一个tag
using UnityEngine;
using System.Collections;
public class EnemyHealthAndDamage : HealthAndDamage {
protected override void Awake()
{
base.Awake();
hp = 100;
attack = 10;
skin = transform.Find("Zombear").GetComponent<SkinnedMeshRenderer>();
}
protected override void Update()
{
base.Update();
if (GameObject.FindGameObjectWithTag("Player").GetComponent<HealthAndDamage>().hp <= 0)
{
this.GetComponent<NavMeshAgent>().Stop();
//获取脚本,并关闭导航
//以下两种写法也行
//this.GetComponent<NavMeshAgent>().Stop();
//this.transform.GetComponent<NavMeshAgent>().Stop();
this.GetComponent<Animator>().SetBool("Walking", false);
//获取脚本,并把Walking参数设置为false
}
}
protected override void Death()
{
base.Death();
this.GetComponent<NavMeshAgent>().Stop();
this.GetComponent<EnemyMove>().enabled = false;
//关闭碰撞箱子
this.GetComponent<CapsuleCollider>().enabled = false;
}
void EnemyDeath()
{
Destroy(this.gameObject, 3f);
}
}