admin管理员组文章数量:1410737
so the main problem is that the Patrol() method is not getting called, its my fist time working with inheritance and I suppose theres something wrong with how Currentstate gets set. My idea was that I write the method in the base class, check the CurrentState in its update method and then just set CurrentState in my enemy - child - scripts but it doesnt seem to work. Can somebody help?
using Assets.Code.Enemy.Enemies;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using Unity.VisualScripting;
using UnityEngine;
public class EnemyBase : MonoBehaviour
{
[Header("Base values")]
private int _health = 0;
private int _damage = 0;
private int _speed = 0;
private EnemyState _currentState;
[Header("Movement elements")]
protected bool playerInRange = false;
[SerializeField] protected CapsuleCollider2D SpotRange; // the range the enemy will be able to see the player
[SerializeField] protected Transform PlayerTransform;
[SerializeField] protected Transform EnemyFirstPosition, EnemySecondPosition;
protected GameObject CurrentEnemy;
virtual protected int Speed
{
get => _speed;
set => _speed = value;
}
virtual protected EnemyState CurrentState
{
get => _currentState;
set => _currentState = value;
}
virtual protected int Health
{
get => _health;
set => _health = value;
}
virtual protected int Damage
{
get => _damage;
set => _damage = value;
}
// Update is called once per frame
void Update()
{
switch (CurrentState)
{
case EnemyState.Patrol:
StartCoroutine(Patrol());
break;
case EnemyState.Chase:
MoveTowardsPlayer();
break;
case EnemyState.Attack:
Attack();
break;
}
}
public virtual void TakeDamage(int damageTotake)
{
Health -= damageTotake;
}
protected virtual void MoveTowardsPlayer()
{
}
protected virtual void Attack() { } //Empty, will be set in each enemy class individually
protected virtual IEnumerator Patrol()
{
Transform nextTargetPoint = EnemyFirstPosition;
while (true)
{
if (nextTargetPoint != null)
{
Debug.Log("move enemy");
CurrentEnemy.transform.position = Vector2.MoveTowards(
CurrentEnemy.transform.position,
nextTargetPoint.transform.position,
Speed * Time.deltaTime
);
if ((CurrentEnemy.transform.position - nextTargetPoint.transform.position).magnitude < 0.1f) //check if the distance between the enemy and the first target point is low, same as Vector.Distance()
{
yield return new WaitForSeconds(1);
nextTargetPoint = (nextTargetPoint == EnemyFirstPosition) ? EnemySecondPosition : EnemyFirstPosition;
}
}
else if (nextTargetPoint == null)
{
nextTargetPoint = EnemyFirstPosition.transform;
}
}
}
protected virtual void Rest()
{
}
protected virtual void Die()
{
Destroy(this.gameObject);
}
protected virtual void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
playerInRange = true;
}
}
protected virtual void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
playerInRange = false;
}
}
}
using Assets.Code.Enemy.Enemies;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LunaticCultistBase : EnemyBase
{
private Animator _enemyAnimator;
private Rigidbody2D _enemyRigidbody;
private SpriteRenderer _enemySpriteRenderer;
// Start is called before the first frame update
void Start()
{
_enemyAnimator = GetComponent<Animator>();
_enemyRigidbody = GetComponent<Rigidbody2D>();
_enemySpriteRenderer = GetComponent<SpriteRenderer>();
base.Health = 20;
base.Damage = 10;
base.Speed = 10;
base.CurrentEnemy = this.gameObject;
base.CurrentState = EnemyState.Patrol;
CurrentEnemy = this.gameObject;
}
// Update is called once per frame
void Update()
{
if (base.Health <= 0)
Die();
if (playerInRange)
{
if (PlayerTransform.position.x < this.gameObject.transform.position.x)
{
_enemySpriteRenderer.flipX = true;
}
else
{
_enemySpriteRenderer.flipX = false;
}
}
}
//hit and damage logic
public override void TakeDamage(int damageTotake)
{
_enemyRigidbody.bodyType = RigidbodyType2D.Static;
base.TakeDamage(damageTotake);
Invoke("SetAnimationAndBodyType", 0.1f);
}
private void SetAnimationAndBodyType()
{
_enemyAnimator.SetTrigger("Hit");
_enemyRigidbody.bodyType = RigidbodyType2D.Dynamic;
}
//death logic
protected override void Die()
{
_enemyAnimator.SetTrigger("Death");
Invoke("InvokeDie", 1f);
}
private void InvokeDie()
{
base.Die();
}
}
public enum EnemyState
{
Patrol,
Chase,
Attack
}
so the main problem is that the Patrol() method is not getting called, its my fist time working with inheritance and I suppose theres something wrong with how Currentstate gets set. My idea was that I write the method in the base class, check the CurrentState in its update method and then just set CurrentState in my enemy - child - scripts but it doesnt seem to work. Can somebody help?
using Assets.Code.Enemy.Enemies;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using Unity.VisualScripting;
using UnityEngine;
public class EnemyBase : MonoBehaviour
{
[Header("Base values")]
private int _health = 0;
private int _damage = 0;
private int _speed = 0;
private EnemyState _currentState;
[Header("Movement elements")]
protected bool playerInRange = false;
[SerializeField] protected CapsuleCollider2D SpotRange; // the range the enemy will be able to see the player
[SerializeField] protected Transform PlayerTransform;
[SerializeField] protected Transform EnemyFirstPosition, EnemySecondPosition;
protected GameObject CurrentEnemy;
virtual protected int Speed
{
get => _speed;
set => _speed = value;
}
virtual protected EnemyState CurrentState
{
get => _currentState;
set => _currentState = value;
}
virtual protected int Health
{
get => _health;
set => _health = value;
}
virtual protected int Damage
{
get => _damage;
set => _damage = value;
}
// Update is called once per frame
void Update()
{
switch (CurrentState)
{
case EnemyState.Patrol:
StartCoroutine(Patrol());
break;
case EnemyState.Chase:
MoveTowardsPlayer();
break;
case EnemyState.Attack:
Attack();
break;
}
}
public virtual void TakeDamage(int damageTotake)
{
Health -= damageTotake;
}
protected virtual void MoveTowardsPlayer()
{
}
protected virtual void Attack() { } //Empty, will be set in each enemy class individually
protected virtual IEnumerator Patrol()
{
Transform nextTargetPoint = EnemyFirstPosition;
while (true)
{
if (nextTargetPoint != null)
{
Debug.Log("move enemy");
CurrentEnemy.transform.position = Vector2.MoveTowards(
CurrentEnemy.transform.position,
nextTargetPoint.transform.position,
Speed * Time.deltaTime
);
if ((CurrentEnemy.transform.position - nextTargetPoint.transform.position).magnitude < 0.1f) //check if the distance between the enemy and the first target point is low, same as Vector.Distance()
{
yield return new WaitForSeconds(1);
nextTargetPoint = (nextTargetPoint == EnemyFirstPosition) ? EnemySecondPosition : EnemyFirstPosition;
}
}
else if (nextTargetPoint == null)
{
nextTargetPoint = EnemyFirstPosition.transform;
}
}
}
protected virtual void Rest()
{
}
protected virtual void Die()
{
Destroy(this.gameObject);
}
protected virtual void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
playerInRange = true;
}
}
protected virtual void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("Player"))
{
playerInRange = false;
}
}
}
using Assets.Code.Enemy.Enemies;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LunaticCultistBase : EnemyBase
{
private Animator _enemyAnimator;
private Rigidbody2D _enemyRigidbody;
private SpriteRenderer _enemySpriteRenderer;
// Start is called before the first frame update
void Start()
{
_enemyAnimator = GetComponent<Animator>();
_enemyRigidbody = GetComponent<Rigidbody2D>();
_enemySpriteRenderer = GetComponent<SpriteRenderer>();
base.Health = 20;
base.Damage = 10;
base.Speed = 10;
base.CurrentEnemy = this.gameObject;
base.CurrentState = EnemyState.Patrol;
CurrentEnemy = this.gameObject;
}
// Update is called once per frame
void Update()
{
if (base.Health <= 0)
Die();
if (playerInRange)
{
if (PlayerTransform.position.x < this.gameObject.transform.position.x)
{
_enemySpriteRenderer.flipX = true;
}
else
{
_enemySpriteRenderer.flipX = false;
}
}
}
//hit and damage logic
public override void TakeDamage(int damageTotake)
{
_enemyRigidbody.bodyType = RigidbodyType2D.Static;
base.TakeDamage(damageTotake);
Invoke("SetAnimationAndBodyType", 0.1f);
}
private void SetAnimationAndBodyType()
{
_enemyAnimator.SetTrigger("Hit");
_enemyRigidbody.bodyType = RigidbodyType2D.Dynamic;
}
//death logic
protected override void Die()
{
_enemyAnimator.SetTrigger("Death");
Invoke("InvokeDie", 1f);
}
private void InvokeDie()
{
base.Die();
}
}
public enum EnemyState
{
Patrol,
Chase,
Attack
}
Share
Improve this question
edited Mar 10 at 19:30
derHugo
91.3k9 gold badges91 silver badges135 bronze badges
asked Mar 8 at 19:13
JULUXX JULUXJULUXX JULUX
1
1 Answer
Reset to default 0Your subtype LunaticCultistBase
is hiding Update
meaning it has it's own implementation and the Update
of EnemyBase
might not get called! That's because these Unity built-in event message methods are invoked by Unity's event loop system and not like "normal" methods. And that event system is probably going by the most specific type.
So to be sure you should rather make those Unity methods always protected virtual
in base types so you can then safely overwrite/extend them in subtypes!
本文标签: cUnity 2d enemy patrolling not working properlyStack Overflow
版权声明:本文标题:c# - Unity 2d enemy patrolling not working properly - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744887863a2630594.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论