【问题标题】:How to change a parent class variable from child class in unity如何统一从子类更改父类变量
【发布时间】:2019-03-09 00:59:18
【问题描述】:

我刚刚开始使用 Unity,我正在使用面向角色的 OOP 原则制作一个基本的 2d 游戏。 我创建了一个名为 EnemyController 的通用敌人类,它有一个名为 BasicEnemy 的子类。

这个想法是,当敌人产生时(在两个点之间,在这种情况下是床和酒吧),它要么向左要么向右移动并开始在物体之间巡逻。 我为此使用了光线投射,到目前为止,当敌人击中其中任何一个点时,我已经让光线与精灵一起翻转。 我似乎无法让精灵朝新翻转的方向移动。

我尝试修改父类中的moveSpeed变量,并尝试编写自己的移动函数LeftMoveRightMove强>。

我的代码如下。

这是父类的代码:

public class EnemyController : MonoBehaviour
{
    //transform for each of the enemies
    protected Transform enemyTransform;
    protected Vector2 startPosition;
    protected int damageValue, healthLevel;
    public int moveSpeed;
    protected int randNum;
    protected Rigidbody2D rb;

    private void Start()
    {
        enemyTransform = transform;
        startPosition = enemyTransform.position;
        rb = GetComponent<Rigidbody2D>();
        randNum = Random.Range(1,3);
        // Debug.Log(randNum);

        if(randNum == 1) {
            Debug.Log("Moves Left at the start");
        } if(randNum == 2) {
            Debug.Log("Moves Right at the start");
            Flip(); 
        }
    }
    private void FixedUpdate()
    {
        Move(); 
    }

    protected virtual void Move()
    {
        if(randNum == 1) {
            rb.velocity = new Vector2(-moveSpeed, rb.velocity.y);
        }
        if(randNum == 2) {
            rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
        }
    }

    public void Flip() {
        Vector3 enemyScale = transform.localScale;
        enemyScale.x *= -1;
        transform.localScale = enemyScale;
    }

}

这是 Child 类的代码:

public class BasicEnemy : EnemyController
{
    //Origin, Direction, Range for Raycasting.
    public Transform rayOriginPoint;
    private Vector2 rayDir = new Vector2(-1,0);
    public float range;

    //GameObjects that it should hit
    GameObject bar, bed;
    EnemyController parentClass;
    private void Start()
    {
        bar = GameObject.Find("minibar");
        bed = GameObject.Find("bed");
    }

    private void Update()
    {
        RaycastHit2D hitObject = Physics2D.Raycast(rayOriginPoint.position,rayDir,range);
        Debug.DrawRay(rayOriginPoint.position,rayDir*range);

        if(hitObject == true) {
            if(hitObject.collider.name == bed.name) {
                Debug.Log(hitObject.collider.name);
                Flip();
                rayDir *= -1;
                LeftMove();
            }
            if(hitObject.collider.name == bar.name) {
                Debug.Log(hitObject.collider.name);
                Flip();
                rayDir *= -1;
                RightMove();
            }
        }
    }

    void LeftMove() {
        rb.velocity = new Vector2(-1, rb.velocity.y);
    }

    void RightMove(){
       rb.velocity = new Vector2(1, rb.velocity.y);
    }
}

有人可以帮我解决这个问题吗? 提前致谢!

【问题讨论】:

  • 为什么不只是翻转精灵而不是改变比例?然后使用 x/y 作为它们的自然轴
  • @BugFinder 不会和我写的 Flip 函数一样吗?照原样,精灵翻转。你能给我一个代码示例来理解吗? :)
  • GetComponent().flipX = true; transform.scale 改变了其他东西。
  • @BugFinder 还有一些对撞机和其他东西也需要翻转。这就是我使用 transform.scale 位的原因。主要是因为我对此有点陌生。
  • 如果你的敌人向 + 或 - 移动方向移动,看起来 randNum 会发生变化,而这在你的 Flip 函数中永远不会改变

标签: c# unity3d


【解决方案1】:
 private void FixedUpdate()
    {
        Move(); 
    }
protected virtual void Move()
{
    if(randNum == 1) {
        rb.velocity = new Vector2(-moveSpeed, rb.velocity.y);
    }
    if(randNum == 2) {
        rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
    }
}

您的基本控制器中的上述块根据 randNum 告诉您的敌人向哪个方向移动。

void LeftMove() {
        rb.velocity = new Vector2(-1, rb.velocity.y);
    }

    void RightMove(){
       rb.velocity = new Vector2(1, rb.velocity.y);
    }

你继承的控制器中的这个块会翻转速度。

从左/右移动翻转速度后,FixedUpdate 立即调用并调用 Move,然后将速度更改回 randNum 中的值

建议的解决方案: 存储一个 bool directionRight,在创建时随机化它的值,

在您的固定更新移动中

if(directionRight)
    rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
else
   rb.velocity = new Vector2(-moveSpeed, rb.velocity.y);

让您的翻转函数调用 directionRight =!directionRight 来翻转方向。 不再需要您的左/右移动功能

【讨论】:

  • 我明白你所说的逻辑。我仍然想不出办法来解决它。你能帮我解决这个问题吗?
  • 好的,现在写
  • 我尝试了您的解决方案。所以发生的情况是,当精灵向左移动时,start() 中的布尔值设置为 false,向右移动时设置为 true,然后当 @987654325 @通过FixedUpdate()调用,布尔值重置为false。发生这种情况,我在rb.velocity = new Vector2(moveSpeed, rb.velocity.y); 有一个“NullReferenceException: Object reference not set to an instance of an object”@关于我在哪里做错的任何想法?
【解决方案2】:

我设法通过覆盖子类中的父函数来解决这个问题。

private bool facingRight;

    private void Start()
    {
        bar = GameObject.Find("minibar");
        bed = GameObject.Find("bed");

        rb = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        RaycastHit2D hitObject = Physics2D.Raycast(rayOriginPoint.position,rayDir,range);
        Debug.DrawRay(rayOriginPoint.position,rayDir*range);

        if(hitObject == true) {
            if(hitObject.collider.name == bed.name) {
                Debug.Log(hitObject.collider.name);
                rayDir *= -1;
                facingRight = true;
                Flip();
            }
            if(hitObject.collider.name == bar.name) {
                Debug.Log(hitObject.collider.name);
                rayDir *= -1;
                facingRight = false;
                Flip();
            }
        }
    }

    protected override void Move()
    {
        // rb.velocity = new Vector2(moveSpeed, rb.velocity.y);
        base.Move();
        if(facingRight == false) {
            rb.velocity = new Vector2(-1, rb.velocity.y);
        }
        else {
            rb.velocity = new Vector2(1,rb.velocity.y);
        }
    }

就像@Prodigle 所说,我更改了一个布尔值以翻转精灵。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-12
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    相关资源
    最近更新 更多