unity3d5.0进阶-官方案例《Unity5.0Survival Shooter》 扫二维码继续学习 二维码时效为半小时

(18 评论)

免费

//相机更随

public class CameraFollor : MonoBehaviour {
    public GameObject Player;
    private Vector3 offest;
    
    void Start () {
        offest = transform.position - Player.transform.position;
    
    }
    
    
    void Update () {
    
    }
    void FixedUpdate()
    {
        transform.position = Player.transform.position + offest;
    }

[展开全文]

有一个脚本名为PlayerMovement控制角色移动

声明PlayerMovement playerMovement;

awake( )里赋playerMovement=GetComponent<PlayerMovement>();

playerMovement.enabled=false;即可使角色控制失效;

[展开全文]

游戏结束界面UI

Scale全部为0时,文字会看不见

可以添加动画做渐变效果

做好动画片段后再添加到动画控制器中

(好像会自动生成)

添加相关条件后再用脚本控制在适当的时候出现就好了就好了

gameovermanager

public PlayerHealth playerHealth;

Animator anim;

void Awake(){

anim = GetComponent<Animator>();

}

void Updata(){

  if(playerHealth.currentHealth<=0){

  anim.SetTrigger("Gameover");

}

}

[展开全文]

使用UI制作受到攻击效果

创建Image

color-alpha ←可以调整透明度

HealthSlider 模拟血条

把小滑块去掉

血条的减少即修改通过value的值即可。

using UnityEngine.UI;

public Slider healthSlider;

public Image damageImage;

public float flashSpeed=5f;

public color flashColour = new Color(1f,0f,0f,0.1f);

//通过编辑器拖过来就好

void Updata(){

 if(damaged){

  damageImage.color = flashcolour;

}

 else {

  damageImage.color = Color.Lerp(damageImage.color,Color.clear,flashSpeed*Time.deltatime);

//color.clear表示RGBA(0.0.0.0)

//有渐变的效果

}

damaged=false;

}

 

在受到伤害时

healthSlider.value=currentHealth;

[展开全文]

添加音乐(Audio Sourse)

例子:

Public AudioClip deathClip;

AudioSource playerAudio

初始化:

playerAudio = GetComponent<AudioSource>();

//已经接好相应的声音了

收到伤害

playerAudio.Play();

死亡时

playerAudio.clip=deathClip;

playerAudio.Play();

 

 

[展开全文]

创建怪物生成点(使用空对象)

创建怪物管理

EnemyManager

public playerHealth playerHealth;

public GameObject enemy;

public float SpawnWaitTime = 2f;

//刚开始的等待时间

public float SpawnTime = 3f;

//怪物重复生成的时间间隔

public Transform[] spawnPoints;

//直接把怪物生成点拖进去即可

 

void Start(){

 InvokeRepeating("Spwan",SpawnWaitTime,SpawnTime);

//等待SpawnWaitTime后每隔spawnTime时间调用Spwan()方法

}

//怪物的生成

void Spawn(){

  if(playerHealth.currentHealth <=0f)

     return;

  int spawnPointIndex= Random.Range(0,spawnPoint.Length); 

  Instantiate(enemy,spaenPoints[spawnPointIndex].position,spawnPoints[spawnPointIndex].rotation);//生成怪物

}

 

同一个脚本可多次利用

[展开全文]

bool isSinking;

public float sinkSpeed = 2.5f;

isSinking = ture;

Is knemabtic

GetComponent<Rigidbody>().isKinematic=true;

 

void Update(){

if(isSinking){

transform.Translate(-Vector3.up*sinkSpeed*Time.deltaTime);

//让怪物下沉

//transform.Translate()平移

}

}

[展开全文]

在生命值脚本中 

playershooting playerShooting

 playerShooting = GetComponentInChildren<PlayerShooting>();

死亡时

playerShooting.enabled = false;

 

EnemyHealth中

ParticleSystem hitParticle;

hitParticles = GetComponentInChildren<ParticleSystem>();

 

public void TakeDamage(int amount,Vector3 hitpoint){

hitParticles.transform.position = hitPoint;

hitParticles.Play();

//在碰撞点处播放粒子效果

}

 

public void StaetSinking(){

  GetComponent<NavMeshAgent>().enabled = false;

 //取消导航

  Destroy(gameObject,2f);

  //在两秒内销毁物体

}

 

EnemyMovement

EnemyHealtn enemyHealth;

PlayerHealth playerHealth;

 

enemyHealth = GetComponent<enemyHealth>();

playHealth = player.GetComponent<PlayerHealth>();

 

if(enemyHealth.currentHealth>0&&playHealth.currentHealth>0)

else

nav.enabled = false;

[展开全文]

主角攻击 PlayerShooting

Line Handerer

线的渲染器

Positions 设置起始点与结束点

Light 模拟发光的效果

public int damagePerShot = 20;

public float timeBetweenBullets = 0.15f;

//每发子弹的时间间隔

public float range = 100f;//开火范围

 

float timer;

Ray shootRay;

RaycastHit shootHit; //保存射线碰撞的结果信息

 

int shootableMask;

//射击有效果层

ParticleSystem gunParticles;

LineRenderer gunLine;

Light gunLight;

float effectsDisplayTime=0.2f;

//开火效果持续时间的百分比

 

void Awake(){

shootableMask = LayerMask.GetMask("Shootable");

//依次初始化

}

 

void Updata(){

timer += Time.deltatime;

if(Input.GetButton("Firel")&& timer >=timeBetweenBullets && Time.timeScale!=0){

  Shoot();

}

if(timer >= timeBetweenBullets*effectsDisplayTime){

DisableEffects();

}

}

public void DisableEffects(){

  gunLine.enabled = false;

  gunLight.enabled = false;

}

void Shoot(){

  timer = 0f;

  gunLight.enabled = true;

  gunParticles.Stop();

  gunParticles.Play();

 

  gunLine.enabled = true;

  gunLine.setPosition(0,transform.position);

//设置渲染器的第一个点位置

 

shootRay.origin = transform.position;

shootRay.direction = transform.forward;

//射线的位置及方向

if(Physics.Raycast(shootRay,out shootHit,Range,shootableMask)){

//如果射线碰到东西

EnemyHealth enemyHealth = shootHit.collider.GetComponent<EnemyHealth >();

if(enemyHealth!=null){

//碰到的是敌人则造成伤害

enemyHealth.TakeDamage(damagePerShot);

}

gunLine.SetPosition(1,shootHit.point);

//设置线渲染器第二个点的信息,从而构建出一条线段

}

else{

gunLine.gunLine.SetPosition(1,shootRay.origin +shootRay.direction*range);

//能够到达的最远距离

}

}

[展开全文]

主角攻击 PlayerShooting

Line Handerer

线的渲染器

Positions 设置起始点与结束点

Light 模拟发光的效果

public int damagePerShot = 20;

public float timeBetweenBullets = 0.15f;

//每发子弹的时间间隔

public float range = 100f;//开火范围

 

float timer;

Ray shootRay;

RaycastHit shootHit; //保存射线碰撞的结果信息

 

int shootableMask;

//射击有效果层

ParticleSystem gunParticles;

LineRenderer gunLine;

Light gunLight;

float effectsDisplayTime=0.2f;

//开火效果持续时间的百分比

 

void Awake(){

shootableMask = LayerMask.GetMask("Shootable");

//依次初始化

}

 

void Updata(){

timer += Time.deltatime;

if(Input.GetButton("Firel")&& timer >=timeBetweenBullets && Time.timeScale!=0){

  Shoot();

}

if(timer >= timeBetweenBullets*effectsDisplayTime){

DisableEffects();

}

}

public void DisableEffects(){

  gunLine.enabled = false;

  gunLight.enabled = false;

}

void Shoot(){

}

[展开全文]

动画

添加事件

RestartLevel

在PlayerHealth中添加相应脚本

public void RestartLevel(){

Application.LoadLevel(Application.loadedLevel); //重新加载当前关卡

}

//公共的函数

 

windows - lighting

勾选掉Cortinous Baking

然后Build一遍,会得到灯光贴图

这样画面再载入时不会变黑

 

[展开全文]

EnemyAttack

public float timeBetweenAttacks = 3.5f;

public int attackDamage = 10;

 

Animator anim;

GameObject player;

playerHealth playerHealth;

EnemyHealth enemeHealth;

bool playerInRange;

//是否在攻击范围内

float timer;

 

voide Awake(){

player= GameObject.FindGameObjectwithTag("player");

playerHealth=player.GetComponent<playerHealth>();

enemeHealth=GetComponent<enemeHealth>();

anim=GetComponent<Animator>();

}

 

void OnTriggerEnter(Collider other){

if(other.gameObject==player){

     playerInRange = true;

}

}

void OnTriggerExit(Collider other){

if(other.gameObject==player){

     playerInRange = false;

}

}

 

void Updata(){

timer += Time.deltatime;

//计时器进行计时

if(playerInRange && timer >=timeBetweenAttacks && enemeHealth.currentHealth>0){

Attack();

}

if(playerHealth.currentHealth <=0){

anim.setTrigger("PlayerDead");

//播放怪物空闲状态

}

}

 

void Attack(){

timer = 0f;

if(PlayerHealth.currentHealth>0){

PlayerHealth.TakeDamage(attackDamage);

}

}

[展开全文]

EnemyHealth 敌人生命值

CapsuleCollider capsulecollider;

void Death(){

isDead=true;

capsulecollider.isTrigger = true;

//变成触发器,不会挡住子弹的光线

anim.SetTrigger("Dead");

}

[展开全文]

Nav Mesh Agent 导航代理

Navigation

烘焙图形很有用

烘焙前环境场景Static要勾选上

Clear 可以取消原有的导航

EnemyMovement

Transform player;

NavMeshAgent nav;

void Awake(){

player=GameObject.FindGameObjectwithTag("Player").transform;

nav =GetComponent<NavMeshAgent>();

}

void updata(){

nav.SetDestination(player.position);

//设置怪物自动导航的目标

}

[展开全文]

PlayerDead 主角死亡

则敌人不再追击

体型差不多的模型动画可以共用

Animator Overide Contronller 

动画覆盖控制器

可以把其他模型的动画控制器拿来用,只是修改了动画片段而已,免得重复一遍操作

[展开全文]

PlayerHealth 玩家生命值

public int staringHealth = 100;

public int currentHealth;

PlayerMovement playerMovement;

Animator anim;

bool isDead; //是否死亡

bool damaged; //是否收到伤害

 

void Awake(){

playerMovement =GetComponont<PlayerMovement>();

anim=GetComponont<Animator>();

currentHealth=staringHealth;

//记得赋初值

}

public void TakeDamage(int amount){

  damaged = ture;

  currentHealth -= amount;

  if(currentHealth<=0 && !isDead){

         Death();

}

}

 

void Death(){

  isDead = true;

  anim.setTrigger("Die");

  playMovement.enabled = false;

   //禁用玩家控制

}

 

[展开全文]

摄像机跟随

CameraFollow

public Transform target;

public float smoothing=5f;

Vector3 offset;

Vector3 offset;

void Start(){

  offset = transform.position - target.position;

//相对位置

}

 

void FixedUpdata(){

Vector3 targetCampos=taeget.position + offset;

//保持目标与摄像机之间的相对位置

transform.position = Vector3.Lerp(transform.position,targetCampos,smoothing*Time.deltatime);

//让摄像机从自身位置到目标位置进行移动

}

[展开全文]

人物跟随鼠标旋转

int floorMask;

float camRayLength = 100f;

 

floorMask=LayerMask.GetMask("Floor");

 

void Turning(){

Ray CamRay = Camera.main.ScreenPointToRay(Input.mousePosition);

//根据当前鼠标的位置,从摄像机发射一条射线,返回射线

RaycastHit floorHit;

if(Physics.Raycast(CamRay,floorHit,camRayLength,floorMask)){

Vector3 playerToMouse=floorHit.point-transform.position;

playerToMouse.y=0f;

Quaternion newRotation=Quaternion.LookRotation(playerToMouse);

//构造一个旋转数

playerRidibody.MoveRotation(newRotation);

}

//Raycast光线投射

}

[展开全文]

Animator anim;

 

anim=Getcomponent<Animator>();

 

void Animating(float h, float v){

 bool walking = h !=0f || v!=0f;

 //判断当前角色是否移动

anim.setBool("IsWaking",walking);

}

 

Quad 小面片

可作为碰撞层,不需要渲染出来

 

[展开全文]

Any State 任意状态

转移条件点击中间的线即可设置

Entry 入口 紧跟着的就是角色默认初始状态

[展开全文]