慕课英雄各个C#脚本分析

一、玩家移动脚本

using UnityEngine;
using System.Collections;

public class PlayerMove : MonoBehaviour {

    public float moveSpeed = 10.0f;	//玩家移动速度
    public float rotateSpeed = 40.0f;	//玩家旋转速度
    public float jumpVelocity = 2.0f;	//玩家起跳速度

        //公有变量可以在U3D的脚本设定界面修改参数

    private Animator animator;		//玩家的Animator组件,用于控制玩家动画的播放
    private Rigidbody rigidbody;	//玩家的刚体组件

    private float h;				//获取玩家横轴输入
    private float v;				//获取玩家纵轴输入
    private bool isGrounded;		        //玩家是否在地面上
    private float groundedRaycastDistance = 0.1f;	//表示向地面发射射线的射线长度

	//初始化,获取玩家组件
    void Start () {
		animator= GetComponent<Animator> ();	//获取玩家Animator组件
                rigidbody = GetComponent<Rigidbody>();	//获取玩家刚体组件
    }

	//每个固定时间执行一次,用于物理模拟
    void FixedUpdate()
    {
		//从玩家的位置垂直向下发出长度为射线,返回值表示玩家是否该射线是否碰撞到物体,该句代码用于检测玩家是否在地面上。三个参数分别是射线位置,射线方向,射线长度。
        isGrounded = Physics.Raycast(transform.position, -Vector3.up, groundedRaycastDistance);
        Jump(isGrounded);	//调用跳跃函数
    }

	//跳跃函数,用于FixedUpdate()中调用
	void Jump(bool isGround)
	{
		//当玩家按下跳跃键Space,并且玩家在地面上时执行跳跃相关函数
		if (Input.GetKey(KeyCode.Space) && isGround)
		{
			//给玩家刚体组件添加向上的作用力,以改变玩家的运动速度,改变值为jumpVelocity
			rigidbody.AddForce(Vector3.up * jumpVelocity, ForceMode.VelocityChange);	
			animator.SetBool("isJump", true);	//设置动画参数,将isJump布尔型参数设置为true,播放玩家跳跃动画
		}
		else if(isGround) animator.SetBool("isJump", false);	//设置动画参数,将isJump布尔型参数设置为false,停止播放玩家跳跃动画
	}

	//每帧执行一次,用于玩家的位移与旋转
	void Update () {
        float h = Input.GetAxisRaw("Horizontal");	//获取玩家水平轴上的输入,默认输入为ad与左右键
        float v = Input.GetAxisRaw("Vertical");		//获取玩家垂直轴上的输入,默认为sw与上下键
        MoveAndRotate(h, v);		//根据玩家在水平、垂直轴上的输入,调用玩家的位移与旋转函数
    }

	//玩家的位移与旋转函数
    void MoveAndRotate(float h, float v)
    {
		//v>0表示获取玩家向前的输入,玩家以moveSpeed的速度向前运动
        if (v > 0) transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);	
		//v<0表示获取玩家向后的输入,玩家以moveSpeed的速度向后运动
        else if (v < 0) transform.Translate(-Vector3.forward * moveSpeed * Time.deltaTime);	

		//若玩家垂直轴上有输入,则表示玩家进行位移,设置动画参数,将isMove布尔型参数设置为true,播放玩家奔跑动画
        if (v != 0.0f) animator.SetBool("isMove", true);
		//若玩家垂直轴上无输入,则表示玩家没有位移,设置动画参数,将isMove布尔型参数设置为false,停止播放玩家奔跑动画
        else animator.SetBool("isMove", false);

		//根据玩家水平轴的输入进行旋转,顺时针为正方向
        transform.Rotate(Vector3.up * h * rotateSpeed * Time.deltaTime);
    }

}


二、玩家生命值脚本

using UnityEngine;
using System.Collections;

public class PlayerHealth : MonoBehaviour {

	public int health = 10;			//玩家的生命值
	public bool isAlive = true;		//玩家是否存活

	//每帧执行一次,检测玩家是否存活
	void Update () {	
		if (health <= 0)
			isAlive = false;
	}

	//玩家扣血函数,用于GameManager脚本中调用,这个函数是公有的,需要被其他脚本调用。
	public void TakeDamage(int damage){
		health -= damage;
		if (health < 0) 
			health = 0;
	}
}


三、玩家攻击脚本

using UnityEngine;
using System.Collections;

public class PlayerAttack : MonoBehaviour {

    public int shootingDamage = 1;				//玩家射击伤害
    public float shootingRange=50.0f;			//玩家射击范围
    public AudioClip shootingAudio;				//玩家射击音效
    public float timeBetweenShooting = 1.0f;	//射击之间的最小时间间隔(玩家射击动画为1秒,为了使得动画正常播放,该值最好>=1.0f)

	private Animator animator;			//玩家的Animator组件,用于控制玩家动画的播放
    private LineRenderer gunLine;		//玩家的线渲染器组件,用于控制玩家开枪发出的激光射线效果

    private float timer;				//攻击时间间隔,记录玩家从上次射击到现在经过的时间
    private Ray ray;					
    private RaycastHit hitInfo;  //发射的射线反馈的相关信息

	//初始化,获取对象组件,以及初始化变量
	void Start () {
		animator = GetComponentInParent<Animator>();	//获取玩家的Animator组件
		gunLine = GetComponent<LineRenderer>();			//获取玩家的线渲染器组件
        timer = 0.0f;		//将攻击时间间隔清零
	}

	//每帧执行一次,用于玩家的射击行为
	void Update () {
		//当玩家按下攻击键J,并且攻击间隔大于射击之间的最小时间间隔,执行射击相关行为
        if (Input.GetKeyDown(KeyCode.J) && timer>timeBetweenShooting)
        {
            timer = 0.0f;							//射击后将攻击时间间隔清零
			animator.SetBool("isShooting", true);	//设置动画参数,将isShooting布尔型参数设置为true,播放玩家射击动画
			Invoke("shoot", 0.5f);					//玩家举枪花费0.5s,0.5秒后调用shoot() 射击函数
        }
		//否则,表示射击条件未满足
        else
        {
            timer += Time.deltaTime;	//更新攻击间隔,增加上一帧所花费的时间
            gunLine.enabled = false;	//将线渲染器设为禁用
			animator.SetBool("isShooting", false);	//设置动画参数,将isShooting布尔型参数设置为false,停止播放玩家射击动画
        }
	}

	//射击函数
    void shoot()
	{
		AudioSource.PlayClipAtPoint(shootingAudio, transform.position);	//在枪口位置播放射击音效
		ray.origin = Camera.main.transform.position;	//设置射线发射的原点:摄像机所在的位置
        ray.direction = Camera.main.transform.forward;	//设置射线发射的方向:摄像机的正方向
        gunLine.SetPosition(0, transform.position);		//设置线渲染器(开枪后的激光射线)第一个端点的位置:玩家枪械的枪口位置(本游戏对象)
        //发射射线,射线有效长度为shootingRange,若射线击中任何游戏对象,则返回true,否则返回false
		if (Physics.Raycast(ray, out hitInfo, shootingRange))
        {
            if (hitInfo.collider.gameObject.tag == "Enemy")	//当被击中的游戏对象标签为Enemy,表明射线射中敌人
            {
				//获取该名敌人的EnemyHealth脚本组件
                EnemyHealth enemyHealth = hitInfo.collider.gameObject.GetComponent<EnemyHealth>();
                if (enemyHealth != null)
                {
					//调用EnemyHealth脚本的TakeDamage()函数,对敌人造成shootingDamage的伤害
					enemyHealth.TakeDamage(shootingDamage);	
                }
				if(enemyHealth.health>0)	//若敌人受伤且未死亡,敌人将会因受到攻击而被击退
					hitInfo.collider.gameObject.transform.position += transform.forward * 2;
            }
			gunLine.SetPosition(1, hitInfo.point);	//当射线击中游戏对象时,将线渲染器(开枪后的激光射线)第二个端点设为射线击中游戏对象的点
        }
		//若射线未射中游戏对象,则将线渲染器(开枪后的激光射线)第二个端点设为射线射出后的极限位置
        else gunLine.SetPosition(1, ray.origin + ray.direction * shootingRange);
		gunLine.enabled = true;	//将线渲染器(开枪后的激光射线)启用,显示玩家开枪后的效果。
    }
}



四、敌人追踪脚本

using UnityEngine;
using System.Collections;

public class EnemyTrace : MonoBehaviour {

	public GameObject target;		//敌人的追踪目标
	public float moveSpeed=8.0f;	//敌人的移动速度
	public float minDist=2.2f;		//追踪距离,当敌人与目标的距离小于等于该值时,敌人不再追踪目标

	private float dist;							//敌人的坐标与玩家坐标的位置
	private Animator animator;				//敌人的Animator组件
	private EnemyHealth enemyHealth;		//敌人的生命值脚本

	//初始化,获取敌人的组件
	void Start () {
		animator = GetComponent<Animator> ();		//获取敌人的Animator组件	
		enemyHealth = GetComponent<EnemyHealth> (); //获取敌人的生命值脚本
	}

	//每帧执行一次,用于敌人追踪目标
	void Update () {
		if (enemyHealth!=null && enemyHealth.health <= 0) return;	//当敌人死亡时,敌人无法追踪目标
		if (target == null) {					//当追踪目标未设置时,敌人无法追踪目标
			animator.SetBool ("isStop", true);	//设置动画参数,将布尔型参数isStop设为true:敌人未追踪目标,播放停驻动画
			return;
		}
		dist = Vector3.Distance (transform.position, target.transform.position);	//计算敌人与追踪目标之间的距离
		//当游戏状态为游戏进行中(Playing)时
		if (GameManager.gm==null || GameManager.gm.gameState == GameManager.GameState.Playing) {			
			if (dist > minDist) {	//当敌人与目标的距离大于追踪距离时
				transform.LookAt (target.transform);				//敌人面向追踪目标
				transform.eulerAngles=new Vector3(0.0f,transform.eulerAngles.y,0.0f);	//设置敌人的Rotation属性,确保敌人只在y轴旋转
				transform.position += 
					transform.forward * moveSpeed * Time.deltaTime;	//敌人以moveSpeed的速度向追踪目标靠近
			}
			animator.SetBool ("isStop", false);	//设置动画参数,将布尔型参数isStop设为false:敌人追踪目标,播放奔跑动画
		}
	}
}


五、敌人生命脚本

using UnityEngine;
using System.Collections;

public class EnemyHealth : MonoBehaviour {

	public int health=2;	//敌人的生命值
	public int value=1;		//玩家击杀敌人后所获得的分数
	public AudioClip enemyHurtAudio;	//敌人的受伤音效

	private Animator animator;			//敌人的Animator组件
	private Collider collider;			//敌人的Collider组件
	private Rigidbody rigidbody;		//敌人的rigidbody组件

	//初始化,获取敌人的组件
	void Start(){
		animator = GetComponent<Animator> ();	//获取敌人的Animator组件
		collider = GetComponent<Collider> ();	//获取敌人的Collider组件
		rigidbody = GetComponent<Rigidbody> ();	//获取敌人的Rigidbody组件
	}

	//敌人受伤函数,用于PlayerAttack脚本中调用
	public void TakeDamage(int damage){	
		health -= damage;			//敌人受伤扣血
		if (enemyHurtAudio != null)	//在敌人位置处播放敌人受伤音效
			AudioSource.PlayClipAtPoint (enemyHurtAudio, transform.position);
		if (health <= 0) {			//当敌人生命值小于等于0时,表明敌人已死亡
			if (GameManager.gm != null) {	
				GameManager.gm.AddScore (value);//玩家获得击杀敌人后得分
			}
			animator.applyRootMotion = true;	//设置Animator组件的ApplyRootMotion属性,使敌人的移动与位移受动画的影响
			animator.SetTrigger ("isDead");		//设置动画参数,设置isDead的Trigger参数,播放敌人死亡动画
			collider.enabled = false;			//禁用敌人的collider组件,使其不会与其他物体发生碰撞
			rigidbody.useGravity = false;		//因为敌人的collider组件被禁用,敌人会因重力穿过地形系统下落,取消敌人受到的重力可以避免该现象
			Destroy (gameObject, 3.0f);			//3秒后删除敌人对象
		}
	}
}


六、敌人攻击脚本

using UnityEngine;
using System.Collections;

public class EnemyAttack : MonoBehaviour {

	public int damage=1;					//敌人攻击造成的伤害值
	public float timeBetweenAttack=0.8f;	//敌人攻击之间的最小间隔(敌人攻击动画约为0.8秒,为了使得动画正常播放,该值最好设为0.8秒)
	public AudioClip enemyAttackAudio;		//敌人的攻击音效

	private float timer;				//攻击时间间隔,记录敌人从上次攻击到现在经过的时间
	private Animator animator;			//敌人的Animator组件,用于控制敌人动画的播放
	private EnemyHealth enemyHealth;	//敌人的生命值脚本

	//初始化,获取对象组件,以及变量初始化
	void Start(){
		timer = 0.0f;								//将攻击时间间隔初始化
		animator = GetComponent<Animator> ();		//获取敌人的Animator组件	
		enemyHealth = GetComponent<EnemyHealth> ();	//获取敌人的生命值脚本
	}

	//与勾选了isTrigger属性的COllider组件共同用于检测:是否有物体进入敌人的攻击范围
	void OnTriggerStay(Collider collider){
		if (enemyHealth.health <= 0) 	//若敌人生命值小于等于0,则说明敌人已经死亡,不具备攻击能力
			return;
		//当攻击间隔大于敌人攻击之间的最小间隔,且进入敌人攻击范围的对象标签是玩家时
		if (timer>=timeBetweenAttack && collider.gameObject.tag == "Player") {
			//当游戏状态为游戏进行中(Playing)时
			if(GameManager.gm==null || GameManager.gm.gameState==GameManager.GameState.Playing){
				timer=0.0f;			//攻击后将攻击时间间隔清零
				animator.SetBool ("isAttack", true);	//设置动画参数,将isAttack布尔型参数设置为true,播放敌人攻击动画
				if(enemyAttackAudio!=null)				//在敌人位置处播放敌人的攻击音效
					AudioSource.PlayClipAtPoint(enemyAttackAudio,transform.position);
				if (GameManager.gm != null)
					GameManager.gm.PlayerTakeDamage (damage);//通过GameManager游戏管理类实现玩家扣血的效果
			}
		}
	}

	//与勾选了isTrigger属性的COllider组件共同用于检测:是否有物体离开敌人的攻击范围
	void OnTriggerExit(Collider collider){
		//若离开敌人攻击范围的物体标签是玩家时
		if (collider.gameObject.tag == "Player")
			animator.SetBool ("isAttack", false);	//设置动画参数,将isAttack布尔型参数设置为false,停止播放敌人攻击动画
	}

	//每帧执行一次,更新攻击间隔
	void Update(){
		timer += Time.deltaTime;	//更新攻击间隔,增加上一帧所花费的时间
	}
}


七、游戏控制脚本

using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class GameManager : MonoBehaviour {

	static public GameManager gm;		//静态游戏管理器,场景中唯一的游戏管理器实例

	public GameObject player;			//玩家对象
	private PlayerHealth playerHealth;	//玩家的生命值脚本

	public int TargetScore=10;			//游戏获胜的目标分数
	private int currentScore;			//游戏当前得分

	//游戏状态枚举,分别表示游戏进行(Playing)、游戏失败(GameOver)、游戏胜利(Winning)
	public enum GameState {Playing,GameOver,Winning};	
	public GameState gameState;			//游戏状态变量

    public Text scoreText;				//GUI控件,用于显示当前游戏得分的文本信息
    public Text healthText;				//GUI控件,用于显示玩家当前的生命值

	//初始化,获取相关组件,并初始化变量
	void Start () {
		//初始化游戏管理器类
		gm = GetComponent<GameManager> ();	
		//根据标签获取玩家对象
		if (player == null)
			player = GameObject.FindGameObjectWithTag ("Player");	

		//游戏开始前初始化变量
		currentScore = 0;
		//获取玩家对象的玩家生命值脚本
		playerHealth = player.GetComponent<PlayerHealth> ();
	}

	//每帧执行一次,用于游戏状态的检测与切换,以及处理当前游戏状态需要执行的语句
	void Update () {
		switch (gameState) {	//根据当前游戏状态来决定要执行的语句

		//当游戏状态为游戏进行中(Playing)状态时
		case GameState.Playing:	
            scoreText.text = "Score:" + currentScore;			//将显示当前游戏得分的文本信息更改为“Score:分数”
			healthText.text = "Health:" + playerHealth.health;	//将显示玩家当前生命值的文本信息更改为“Health:生命值”
			//若玩家死亡,游戏状态更改为游戏失败(GameOver)
			if (playerHealth.isAlive == false)
				gm.gameState = GameState.GameOver;
			//若当前得分大于目标分数,游戏状态更改为游戏胜利(Winning)
			else if (currentScore >= TargetScore)
				gm.gameState = GameState.Winning;
			break;
		
		//当游戏状态为游戏胜利(Winning)状态时
		case GameState.Winning:
            SceneManager.LoadScene("level1");	//加载场景level1
            break;
		
		//当游戏状态为游戏失败(GameOver)状态时
		case GameState.GameOver:
			SceneManager.LoadScene("level1");	//加载场景level1
            break;
		}
	}

	//玩家击杀得分
	public void AddScore(int value){
		currentScore += value;
	}

	//玩家受伤扣血
	public void PlayerTakeDamage(int value){
		if (playerHealth != null)
			playerHealth.TakeDamage(value);
	}
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值