[Unity Demo]从零开始制作空洞骑士Hollow Knight第五集:再制作更多的敌人

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

如标题所示,最近感觉有些没活了,或者说是趁热打铁再制作更多的敌人,于是本期的主角就决定是两个大家刚进入空洞骑士就经常看到的敌人另一个爬虫Crawler和飞虫Fly。


一、制作敌人另一个爬虫Crawler

1.公式化导入制作另个爬虫Crawler素材

首先我们先完成Crawler的完整行为,第一步导入素材,分别为它制作tk2dspritecollection和tk2dspriteanimation, 

 

  然后就到了公式化设置一个敌人的时候了Rb2d , audiosource, boxcollider2d:

可以看到它不需要其它的子物体,因为只需要执行行走,死亡,转向的状态。 

2.制作另一个爬虫Crawler的Crawler.cs状态机

创建同名函数给该游戏对象

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Crawler : MonoBehaviour
{
    public float speed;
    [Space]
    private Transform wallCheck; //墙面检测的位置
    private Transform groundCheck; //地面检测的位置
    private Vector2 velocity; //记录速度
    private CrawlerType type;

    private Rigidbody2D body;

    private tk2dSpriteAnimator anim;

    private void Awake()
    {
	body = GetComponent<Rigidbody2D>();

	anim = GetComponent<tk2dSpriteAnimator>();
    }

    private void Start()
    {
	float z = transform.eulerAngles.z;
	//通过transform.eulerAngles.z来判断哪种类型的Crawler
	if (z >= 45f && z <= 135f)
	{
	    type = CrawlerType.Wall;
	    velocity = new Vector2(0f, Mathf.Sign(-transform.localScale.x) * speed);
	}
	else if (z >= 135f && z <= 225f)
	{
	    type = ((transform.localScale.y > 0f) ? CrawlerType.Roof : CrawlerType.Floor);
	    velocity = new Vector2(Mathf.Sign(transform.localScale.x) * speed, 0f);
	}
	else if (z >= 225f && z <= 315f)
	{
	    type = CrawlerType.Wall;
	    velocity = new Vector2(0f, Mathf.Sign(transform.localScale.x) * speed);
	}
	else
	{
	    type = ((transform.localScale.y > 0f) ? CrawlerType.Floor : CrawlerType.Roof);
	    velocity = new Vector2(Mathf.Sign(-transform.localScale.x) * speed, 0f);
	}
	//TODO:
	CrawlerType crawlerType = type;
	if(crawlerType != CrawlerType.Floor)
	{
	    if(crawlerType - CrawlerType.Roof <= 1)
	    {
		body.gravityScale = 0;//如果在墙面面上rb2d的重力就设置为1
				     
	    }
	}
	else
	{
	    body.gravityScale = 1; //如果在地面上rb2d的重力就设置为1
	    //TODO:
	}
	StartCoroutine(Walk());
    }

    /// <summary>
    /// 使用协程实现Walk函数,循环直至hit=true后挂起然后启用协程Turn()
    /// </summary>
    /// <returns></returns>
    private IEnumerator Walk()
    {
	for(; ; )
	{
	    anim.Play("Walk");
	    body.velocity = velocity;
	    bool hit = false;
	    while (!hit)
	    {
		if(CheckRayLocal(wallCheck.localPosition,transform.localScale.x > 0f ? Vector2.left : Vector2.right, 1f))
		{
		    hit = true;
		    break;
		}
		if (!CheckRayLocal(groundCheck.localPosition, transform.localScale.y > 0f ? Vector2.down : Vector2.up, 1f))
		{
		    hit = true;
		    break;
		}
		yield return null;
	    }
	    yield return StartCoroutine(Turn());
	    yield return null;
	}
    }

    /// <summary>
    /// 使用协程实现转向函数
    /// </summary>
    /// <returns></returns>
    private IEnumerator Turn()
    {
	body.velocity = Vector2.zero;
	yield return StartCoroutine(anim.PlayAnimWait("Turn"));
	transform.SetScaleX(transform.localScale.x * -1f);
	velocity.x = velocity.x * -1f;
	velocity.y = velocity.y * -1f;
    }

    /// <summary>
    /// 发射射线,检测是否有LayerMask.GetMask("Terrain").collider
    /// </summary>
    /// <param name="originLocal"></param>
    /// <param name="directionLocal"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    public bool CheckRayLocal(Vector3 originLocal, Vector2 directionLocal, float length)
    {
	Vector2 vector = transform.TransformPoint(originLocal);
	Vector2 vector2 = transform.TransformDirection(directionLocal);
	RaycastHit2D raycastHit2D = Physics2D.Raycast(vector, vector2, length, LayerMask.GetMask("Terrain"));
	Debug.DrawLine(vector, vector + vector2 * length);
	return raycastHit2D.collider != null;
    }

    private enum CrawlerType
    {
	Floor,
	Roof,
	Wall
    }
}

回到Unity编辑器中,如果你的是开始往左走的话,记得设置speed为负数

只需要这个就行了。我们不需要挂载Lineofsightdetector.cs,这个就是敌人发现敌人到自己攻击范围的脚本

3.制作敌人另个爬虫Crawler的playmaker状态机

创建一个名字叫Crawler的playmaker状态机:

变量和事件如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值