在创建完它们的Animation之后我们还要为他们特定的行径编写脚本,(比如Lizard鳄鱼需要向前移动),向日葵Trophy需要生产阳光,仙人掌Cactus需要向前发射子弹
我们先从向日葵Trophy开始写起,这里我们在Canvas底下创建一个Text
这层灰蒙蒙的是我创建的一个空对象Buttons下的子对象3D Object叫Quad并给它一个material
搞好这些之后我们给刚刚创建的Text一个脚本就叫Stars Display(别忘了挂载)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class StarsDisplay : MonoBehaviour
{
[SerializeField] int stars = 100;
Text starText;
void Start()
{
starText = GetComponent<Text>();
}
//更新当前的星星(在变化以后)
private void UpdateDisplay()
{
starText.text = stars.ToString();
}
//判断是否有足够的行星
public bool HaveEnoughStars(int amount)
{
return stars >= amount ? true : false;
}
//增加星星
public void AddStars(int amount)
{
stars += amount;
UpdateDisplay();
}
//使用星星(创建植物)
public void SpendStars(int amount)
{
if (stars >= amount)
{
stars -= amount;
UpdateDisplay();
}
}
}
编写脚本:
我们还要创建一个Defender的脚本给我们的向日葵Trophy
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Defender : MonoBehaviour
{
[SerializeField] int starCost = 100;
public int GetStarCost()
{
return starCost;
}
public void AddStars(int amount)
{
FindObjectOfType<StarsDisplay>().AddStars(amount);
}
}
那我们到底要在哪里用这个AddStars(int)呢,这里就到了使用动画事件的时候了。
点击你想要的帧数,可以看到Samples 右边有个Add Events像个竖杠,这里就创建好了
点击后在inspector面板可以看到我们把刚刚创建的方法选择好改变它的int的值
当运行游戏时每当运行到这一帧的时候Star的值就会加一次3
我们再来搞一下我们的仙人掌Cactus
他也需要一个Defender.cs来记录生成它需要花费多少Stars
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Defender : MonoBehaviour
{
[SerializeField] int starCost = 100;
public int GetStarCost()
{
return starCost;
}
public void AddStars(int amount)
{
FindObjectOfType<StarsDisplay>().AddStars(amount);
}
}
还需要一个Shooter
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shooter : MonoBehaviour
{
[SerializeField] GameObject projectTile;
[SerializeField] GameObject gun;
AttackSpawner myLaneSpawner;
private void Start()
{
SetLaneSpawner();
}
private void Update()
{
if(IsAttackerInLand())
{
Debug.Log("Shoot");
}
else
{
Debug.Log("Sit and Lane");
}
}
private void SetLaneSpawner()
{
AttackSpawner[] spawners = FindObjectsOfType<AttackSpawner>();
//找到这行路的所有敌人
foreach(var spawner in spawners)
{
//判断是不是在我们这一行
bool IsCloseEnough = (Mathf.Abs( spawner.transform.position.y - transform.position.y ) <= Mathf.Epsilon);
if (IsCloseEnough)
{
myLaneSpawner = spawner; //找到我这条路的生成敌人
}
}
}
private bool IsAttackerInLand()
{
//如果我这条路上的敌人数量小于等于0return false
if(myLaneSpawner.transform.childCount <= 0)
{
return false;
}
else
{
return true;
}
}
public void Fire()
{
Instantiate(projectTile, gun.transform.position, transform.rotation); //生成子弹
}
}
这里我们创建好的空对象Gun就作为发射点
同样我们还要创建一个子弹的Prefab,这里大伙应该都看得懂就不细讲了直接上图
我们还需要给它一个Projectile名字的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
[SerializeField] float speed = 1f;
[SerializeField] float damage = 50f;
void Update()
{
transform.Translate(Vector2.right * speed * Time.deltaTime);
}
private void OnTriggerEnter2D(Collider2D other)
{
var health = other.GetComponent<Health>();
var attacker = other.GetComponent<Attacker>();
if(attacker && health)
{
health.DealDamage(damage);
Destroy(gameObject);
}
}
}
创建敌人:
我们先给它设置好这两项就到脚本的部分
敌人当然需要生命值:
Health的脚本如下
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Health : MonoBehaviour
{
[SerializeField] float health = 100f;
[SerializeField] GameObject deathVFX;
public void DealDamage(float damage)
{
health -= damage;
if(health <= 0)
{
TriggerDeathVFX();
Destroy(gameObject);
}
}
//生成爆炸特效
private void TriggerDeathVFX()
{
if (!deathVFX) return;
GameObject deathVFXObject = Instantiate(deathVFX, transform.position, transform.rotation);
Destroy(deathVFXObject, 1f); //1秒后销毁生成的爆炸特效
}
}
这是向左移动的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Attacker : MonoBehaviour
{
[Range(0, 5)]
float currentSpeed = 1f;
void Update()
{
transform.Translate(Vector2.left * currentSpeed * Time.deltaTime);
}
public void SetMovementSpeed(float speed)
{
currentSpeed = speed;
}
}
进入游戏,敌人就会开始移动了,
有关敌人生成的位置以及点击植物来在场景中生成植物的内容,放在下一篇来讲。