如何修改此统一教程脚本? [英] How to revise this unity tutorial script?

查看:108
本文介绍了如何修改此统一教程脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此有一个Unity官方教程,类似于2D流氓. http://unity3d.com/learn/tutorials/projects/2d-roguelike

So there is a Unity official tutorial, 2D rogue like. http://unity3d.com/learn/tutorials/projects/2d-roguelike

在这些系列中,我想修改,改善敌人的AI以用于学习.

In these series, I want to revise, improve enemy's AI for study purpose.

当敌人遇到隔离墙时,我想绕开或摧毁隔离墙.

I want, when an enemy meets a wall, to circumvent or destroy the wall.

因此,第一个敌人需要认出这堵墙.

So the first enemy needs to recognize the wall.

所以我这样修改了它,但是没有用.有人知道出什么事了吗?

So I revised it like this, but it didn't work. Does anyone have an idea what's going wrong?

MovingObject.cs

MovingObject.cs

using UnityEngine;
using System.Collections;

public abstract class MovingObject : MonoBehaviour {
public float moveTime = 0.1f;
public LayerMask blockingLayer;
private BoxCollider2D boxCollider;
private Rigidbody2D rb2D;
private float inverseMoveTime;

// Use this for initialization
protected virtual void Start () {
    boxCollider = GetComponent<BoxCollider2D>();
    rb2D = GetComponent<Rigidbody2D>();
    inverseMoveTime = 1f / moveTime;
}
protected bool Move(int xDir, int yDir, out RaycastHit2D hit){
    Vector2 start = transform.position;
    Vector2 end = start+new Vector2(xDir, yDir);
    boxCollider.enabled = false;
    hit = Physics2D.Linecast(start, end, blockingLayer);
    boxCollider.enabled = true;
    if(hit.transform == null){
        StartCoroutine(SmoothMovement(end));
        return true;
    }
    return false;
}
protected IEnumerator SmoothMovement(Vector3 end){
    float sqrRemainingDistance = (transform.position-end).sqrMagnitude;
    while(sqrRemainingDistance > float.Epsilon){
        Vector3 newPosition = Vector3.MoveTowards(rb2D.position, end, inverseMoveTime * Time.deltaTime);
        rb2D.MovePosition(newPosition);
        sqrRemainingDistance = (transform.position-end).sqrMagnitude;
        yield return null;
    }
}
protected virtual void AttemptMove<T> (int xDir, int yDir) where T : Component{
    RaycastHit2D hit;
    bool canMove = Move (xDir, yDir, out hit);
    if(hit.transform == null)
        return;

    T hitComponent = hit.transform.GetComponent<T>();

    if(!canMove && hitComponent != null){
        OnCantMove(hitComponent);
        if(hitComponent is Wall)
            OnCantMoveEnemy(hitComponent);
    }
}

protected abstract void OnCantMove<T> (T component) where T : Component;
protected abstract void OnCantMoveEnemy <T> (T component)   where T : Component;
}

和Enemy.cs

using UnityEngine;
using System.Collections;

public class Enemy : MovingObject {
public int playerDamage;
private Animator animator;
private Transform target;
private bool skipMove;
public AudioClip enemyAttack1;
public AudioClip enemyAttack2;

protected override void Start () {
    GameManager.instance.AddEnemyToList(this);
    animator = GetComponent<Animator>();
    target = GameObject.FindGameObjectWithTag("Player").transform;
    base.Start();
}

protected override void AttemptMove<T> (int xDir, int yDir){
    if(skipMove){
        skipMove = false;
        return;
    }
    base.AttemptMove<T>(xDir, yDir);

    skipMove = true;

}
public void MoveEnemy(){
    int xDir = 0;       int yDir = 0;
    if((Mathf.Abs(target.position.x - transform.position.x) > float.Epsilon)){
        xDir = target.position.x > transform.position.x ? 1 : -1;  
    }
    if(Mathf.Abs(target.position.y - transform.position.y) > float.Epsilon){
        yDir = target.position.y > transform.position.y ? 1 : -1;
    }   
    Debug.Log("ydir is "+yDir+" / xdir is "+xDir);
    AttemptMove<Player>(xDir, yDir); 
    AttemptMove<Wall>(xDir, yDir); 
} 

protected override void OnCantMove<T>(T component){ 
    Player hitPlayer = component as Player; 
    animator.SetTrigger("enemyAttack");
    hitPlayer.LoseFood(playerDamage); 
    SoundManager.instance.RandomizeSfx(enemyAttack1, enemyAttack2);
}
protected override void OnCantMoveEnemy<T>(T component){ 
    Wall hitWall = component as Wall;
    Debug.Log("hit wall is "+hitWall.name);
}

}

推荐答案

您不需要添加任何其他方法.

You don't need to add any extra methods.

我通过在MovingObject.csAttemptMove<T>中添加几行来做到这一点:

I've done this by adding few lines in AttemptMove<T> in MovingObject.cs:

Wall wallComponent = hit.transform.GetComponent<Wall>();

并通过以下方式扩展现有条件块:

and by expanding already existing conditional block with:

else if (hit.transform.ToString().Substring(0,4) == "Wall")
{
    OnCantMove(wallComponent);
}

请记住,从现在开始,必须使用墙"式预制件来创建每道可破坏的墙.

Keep in mind that from now on every wall that should be destructible has to be created from "Wall" prefab.

然后,您可以使用条件块修改Enemy.cs OnCantMove<T>方法:

Then you can modify your Enemy.cs OnCantMove<T> method with a conditional block:

if (component is Player){...}

else if (component is Wall){...}

并使用您脚本中已有的代码填充这些内容.

And fill those with code that you already have in your scripts.

这篇关于如何修改此统一教程脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆