当前位置:网站首页>Unity2D horizontal board game tutorial 6 - enemy AI and attack animation
Unity2D horizontal board game tutorial 6 - enemy AI and attack animation
2022-08-03 04:35:00 【Really fine duck】
This section to realize the enemyAI的效果
In order to ensure the code reusability,So we create a parent class enemy here,After all the enemy of the enemy classes extend a parent class
First create a parent class enemy script,命名为Enemy
Then write a simpleEnemy代码
Using the virtual function here,函数前面加上visualSaid this function is a virtual function.In a nutshell what is virtual function here
Virtual functions is an important implement polymorphism in object-oriented languages. When a function method in the statement, 前面带了virtual关键字, This function is a virtual function. It with the virtual function of the realization of the main difference is that it can be rewritten in the derived class(override)(非强制要求). Rewritten as function is also a virtual function, When a class or after the virtual functions exist in the base class were not allowed to appear the same name, 返回值, The parameter types have the same number of virtual function.
Want to know if can find some articles carefully look,这里就不赘述了.
Then we create the enemy after the parent class we're going to create the enemy
我们先在HierarchyCreate an empty column component namedEnemies,Said the enemy collection,Then create an empty child components namedEnemy_Frog,The rest of the operation here is not here,And the character of creation is the same,Here we choose role material package where the frog
But remember to change its layer,To the previously createdEnemy,不然会显示不出来
同样添加collider和Rigidbody
And then let the enemy move
We give the enemy to add animation,And character,这里不再赘述,为了方便管理,我们在Animation文件夹里新建一个文件夹EnemyTo save the animation resources for our enemies
Here we only doidle和run的动画即可,然后我们在AnimatorSet the transformation between the animation
用一个boolVariables can be controlled,run为trueWhen the switch torun动画,run为false切换成idle动画
Then we set the enemy moving boundaries,This and characters to detect run into the ground to add acheckground是一样的操作,我们给Enemy_FrogAdd two empty component,分别命名为left和right,Respectively the frog can move around the border,Then we can adjust the position
然后我们给Enemy_FrogWrite a waste was supposed to control its action,新建一个C#After the file directly drag toEnemy_Frog即可
We open the script,As usual, firstcollider,rigidbody等引用,注意Enemy_Frog要继承Enemy类,And overloading the virtual functionStart,所以Start函数前面要加上override
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy_Frog : Enemy
{
private Collider2D coll;
private Rigidbody2D rb;
public int speed;
//---------The above remains the same----------
public Transform left, right;//The left boundary of reference
private float leftMargin, rightMargin;//FrogCan be moved around the border
private bool faceRight=true;//Start the frog is an right
protected override void Start()
{
base.Start();//调用父类的Start函数
coll = GetComponent<Collider2D>();
rb = GetComponent<Rigidbody2D>();
//Were about to get boundary locationx轴的大小
leftMargin = left.position.x;
rightMargin = right.position.x;
//To prevent the left border to follow the enemy move,After direct destruction
Destroy(left.gameObject);
Destroy(right.gameObject);
}
void Update()
{
Movement();
}
//基础移动
void Movement()
{
//If for the right
if(faceRight)
{
anim.SetBool("run", true);
rb.velocity = new Vector2(speed, rb.velocity.y);
//When the enemy more than right boundary
if (transform.position.x > rightMargin)
{
rb.velocity = new Vector2(0, 0);
transform.localScale = new Vector3(-1, 1, 1);
faceRight = false;
}
}
else
{
anim.SetBool("run", true);
rb.velocity = new Vector2(-speed, rb.velocity.y);
//When the enemy over the left border
if(transform.position.x<leftMargin)
{
rb.velocity = new Vector2(0, 0);
transform.localScale = new Vector3(1, 1, 1);
faceRight = true;
}
}
}
}
The code inside the key comments have been made on,It is important to note about boundary moves will also move the enemy,So we let let them destroy after winning the border around.
Then click run after the enemy so that we can move around,But when the enemy encounter characters enemy would fly,As this is because the enemy and figures are made of circular collision,So will slip out,But can't use box collider,So here we turn the enemy's gravity is a little higher,这里我们调成5即可
And then when the character encounters an enemy,People should have a regardless of animation,So we achieve the effect of the character hit the enemy
We add a regardless of animation characters,接着在AnimatorThere a newbool条件hurtJudge whether the characters by blow,稍微调整一下
其中run,idle和jump都可以切换到hurt状态,条件都是hurt为true,hurtYou can return toidle状态,条件是hurt为false
Then we need to determine whether people encounter the enemy,Let's create a Boolean variable to determine whether people regardless of,When people did not encounter the enemy in the performMovement函数,这里稍微修改一下FixedUpdate函数里的内容,When the character is not strike executionmovement函数
We don't have to trigger here,Because the enemy as a trigger word,The enemy will fall down,因为添加了Rigidbody,所以我们这里用tag判断,我们创建一个Enemytag,把Enemy_Frog的tag改成Enemy
Then we judge object role mettag是否是Enemy,And then at the back of the operation on
Switch animation has not yet been set,所以在SwitchAnim函数修改一下,Put on the ground to note here that the code to the code in the front of the,Or you will prioritise characters in the ground operation,Do not perform characters regardless of operation
We found that people can't stop after click run,This is because we give character of circular collision added smooth physical material,So people can't stop,In order to make the characters can stop,We give people add a box type collider,The circular collision of physical material cancel,Added to the box collider there,然后调整一下位置,A box type collider in,Circular collider in
这样就ok了,We then simple set up characters to enemy head to the enemy and the operation of the jump
Because all the enemies have the operation,So we put this function in the enemy class implementation there
And then in person to carry out the function
Thus to achieve the function of destroying the enemy characters to the enemy head,But this is not perfect,Later we do change again.
最后贴一下代码
Enemy
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour
{
protected Animator anim;
protected virtual void Start()
{
anim = GetComponent<Animator>();
}
public void Death()
{
Destroy(gameObject);
}
}
Enemy_Frog
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy_Frog : Enemy
{
private Collider2D coll;
private Rigidbody2D rb;
public int speed;
//---------The above remains the same----------
public Transform left, right;//The left boundary of reference
private float leftMargin, rightMargin;//FrogCan be moved around the border
private bool faceRight=true;//Start the frog is an right
protected override void Start()
{
base.Start();//调用父类的Start函数
coll = GetComponent<Collider2D>();
rb = GetComponent<Rigidbody2D>();
//Were about to get boundary locationx轴的大小
leftMargin = left.position.x;
rightMargin = right.position.x;
//To prevent the left border to follow the enemy move,After direct destruction
Destroy(left.gameObject);
Destroy(right.gameObject);
}
void Update()
{
Movement();
}
//基础移动
void Movement()
{
//If for the right
if(faceRight)
{
anim.SetBool("run", true);
rb.velocity = new Vector2(speed, rb.velocity.y);
//When the enemy more than right boundary
if (transform.position.x > rightMargin)
{
rb.velocity = new Vector2(0, 0);
transform.localScale = new Vector3(-1, 1, 1);
faceRight = false;
}
}
else
{
anim.SetBool("run", true);
rb.velocity = new Vector2(-speed, rb.velocity.y);
//When the enemy over the left border
if(transform.position.x<leftMargin)
{
rb.velocity = new Vector2(0, 0);
transform.localScale = new Vector3(1, 1, 1);
faceRight = true;
}
}
}
}
playercontroller
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class playercontroller : MonoBehaviour
{
private Rigidbody2D rb;//获得Rigidbody2D组件
private Collider2D coll;//获得Collider2D组件
private Animator anim;//获得动画组件
public float speed, jumpForce;//公开,设置速度和跳跃力
public LayerMask ground;//获得地面图层
public Transform groundCheck;//检测角色是否碰到地面
private bool isJump, isGround;//判断是否按下空格键,判断是否在地面
private int jumpCount;//用来设置角色是几段跳
private int cherries;//计数变量
public Text cherryText;//Cherry countUI组件
private bool isHurt;//Judging by blow
//初始化
void Start()
{
rb = GetComponent<Rigidbody2D>();
coll = GetComponent<Collider2D>();
anim = GetComponent<Animator>();
}
void Update()
{
//如果按下空格键并且在地面上
if (Input.GetKeyDown(KeyCode.Space) && jumpCount > 0)
{
isJump = true;
}
}
private void FixedUpdate()
{
isGround = Physics2D.OverlapCircle(groundCheck.position, 0.1f, ground);
if(!isHurt)
{
Movement();
}
Jump();
SwitchAnim();
}
//基础移动
void Movement()
{
float horizontal = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);//设置x轴的移动
//设置角色的转向问题
if (horizontal != 0)
{
transform.localScale = new Vector3(horizontal, 1, 1);
anim.SetBool("run", true);
}
else
anim.SetBool("run", false);
}
//跳跃
void Jump()
{
//如果在地面设置二段跳
if (isGround)
{
jumpCount = 2;
}
//按下跳跃键且在地面上
if (isJump && isGround)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpCount--;
isJump = false;
}
//按下跳跃键且不在地面上且jumpCount大于0
else if (isJump && !isGround && jumpCount > 0)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
jumpCount--;
isJump = false;
}
}
//切换动画
void SwitchAnim()
{
//如果在下落状态
if (rb.velocity.y < 0 && !isGround)
{
anim.SetBool("fall", true);
anim.SetBool("jump", false);
}
//如果在跳跃状态
if (!isGround && rb.velocity.y > 0)
{
anim.SetBool("jump", true);
}
//If a person regardless of
else if (isHurt)
{
anim.SetBool("hurt", true);
if (Mathf.Abs(rb.velocity.x) < 0.1f)
{
anim.SetBool("hurt", false);
isHurt = false;
}
}
//如果在地面上
else if (coll.IsTouchingLayers(ground))
{
anim.SetBool("fall", false);
}
}
//判断是否碰到物品
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.tag=="Collection")
{
Destroy(collision.gameObject);
cherries++;
cherryText.text = "樱桃:" + cherries;
}
}
//消灭敌人
private void OnCollisionEnter2D(Collision2D collision)
{
//Determine if encounter the enemy
if(collision.gameObject.tag=="Enemy")
{
//消灭敌人
Enemy enemy = collision.gameObject.GetComponent <Enemy>();//To get the enemy parent class reference
if(anim.GetBool("fall"))//Determine whether to fall to the enemy head to destroy the enemy
{
enemy.Death();//调用父类函数
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
anim.SetBool("jump", true);
}
//If the characters on the left side of the enemy
else if(transform.position.x<collision.gameObject.transform.position.x)
{
rb.velocity = new Vector2(-8, rb.velocity.y);
isHurt = true;
}
//If the characters on the right side of the enemy
else if(transform.position.x>collision.gameObject.transform.position.x)
{
rb.velocity = new Vector2(8, rb.velocity.y);
isHurt = true;
}
}
}
}
如有错漏之处,欢迎指正!
边栏推荐
猜你喜欢
随机推荐
【Harmony OS】【ARK UI】ETS 上下文基本操作
接口和协议
探索性测试的概念及方法
11.机器学习基础:机器学习的四个分支
肖sir__简历
富瑞宣布战略交易,以简化运营,持续专注于打造领先的独立全服务型全球投行公司
接口测试实战| GET/POST 请求区别详解
MediaRecorder录制屏幕时在部分机型上报错prepare failed:-22
CobalStrike(CS)基础超级详细版
【Harmony OS】【ArkUI】ets开发 基础页面布局与数据连接
常见亲脂性细胞膜染料DiO, Dil, DiR, Did光谱图和实验操作流程
测试人员的价值体现在哪里
7.Keras开发简介
mysql bool blind
Live | StarRocks technology insider: low base dictionary global optimization
【软件工程之美 - 专栏笔记】35 | 版本发布:软件上线只是新的开始
"Obs" start pushing flow failure: the Output. The StartStreamFailed call process
多肽介导PEG磷脂——靶向功能材料之DSPE-PEG-RGD/TAT/NGR/APRPG
移动流量的爆发式增长,社交电商如何选择商业模式
3.张量运算