I am learning Unity by this Japanese Website.
https://feynman.co.jp/unityforest/game-create-lesson/fps-game/enemy/
I want to use “inheritance” in Unity.
I made a base class in the following.
==========================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyBase : MonoBehaviour
{
// 最大HP.
[SerializeField] protected int maxHp = 3;
// 現在のHP.
protected int hp = 0;
// 攻撃を受けるフラグ.
protected bool canHit = true;protected virtual void Start()
{
Init();
}protected virtual void Update()
{} // --------------------------------------------------------------- /// <summary> /// 初期化処理. /// </summary> // ---------------------------------------------------------------
public virtual void Init()
{
hp = maxHp;
}// --------------------------------------------------------------- /// <summary> /// コライダーエンター処理. /// </summary> /// <param name="col"></param> // ---------------------------------------------------------------
public virtual void OnEnemyColliderEnter(Collision col)
{
Debug.Log(“Even this one does not call” + col.gameObject.name);if (col.gameObject.tag == “Arrow” && canHit == true)
{
Arrowを取得して「Arrow」の敵にヒットした時の処理を実行.
var arrow = col.gameObject.GetComponent();
arrow.OnEnemyHit();
HPを矢の攻撃力分マイナス.
hp -= arrow.Attack;if (hp <= 0)
{
// 死亡時処理.
OnDead();
}
else
{
Debug.Log(gameObject.name + ” に攻撃がヒット。残りHP ” + hp);
// 次回ヒットまでの待機時間.
StartCoroutine(HitWait());
}
}
}// --------------------------------------------------------------- /// <summary> /// 死亡時処理. /// </summary> // ---------------------------------------------------------------
protected virtual void OnDead()
{
Debug.Log(gameObject.name + “を倒しました”);
Destroy(gameObject);
}// --------------------------------------------------------------- /// <summary> /// 攻撃ヒット後次の攻撃が当たるまでの待機処理. /// </summary> // ---------------------------------------------------------------
IEnumerator HitWait()
{
// 指定時間待機してフラグを戻す.
canHit = false;
yield return new WaitForSeconds(0.5f);
canHit = true;
}}
And I made a derived class here.
==========================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class EnemyCrocodile : EnemyBase
Start is called before the first frame update
protected override void Start()
{
base.Start();
}protected override void Update()
{
base.Update();
}
}
And I put a picture of the inspector of Enemy.
My problem is that “public virtual void OnEnemyColliderEnter(Collision col)” does not start, when the arrow hit the enemy.
And I made an arrow.cs here.
==========================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Arrow : MonoBehaviour
{// リジッドボディ.
Rigidbody rigid = null;
// 攻撃処理フラグ.
bool isAttack = true;
// 攻撃力.
public int Attack = 1;
// 自動破壊コル-チン.
Coroutine autoDestroyCor = null;
Start is called before the first frame update
void Start()
{}
Update is called once per frame
void Update()
{} // -------------------------------------------------------------------------- /// <summary> /// 生成時コールバック. /// </summary> // --------------------------------------------------------------------------
public void OnCreated()
{
Init();
}// -------------------------------------------------------------------------- /// <summary> /// 発射. /// </summary> /// <param name="direction"> 発射方向. </param> /// <param name="forceMode"> フォースモード. </param> // --------------------------------------------------------------------------
public void Shoot(Vector3 direction, ForceMode forceMode)
{
rigid.useGravity = false;
rigid.isKinematic = false;rigid.AddForce(direction, forceMode);
// 元の記載↓は削除して、それをそのまま変数に代入する形に変更.
StartCoroutine( AutoDestroy( 1f ) );
autoDestroyCor = StartCoroutine(AutoDestroy(1f));
}// -------------------------------------------------------------------------- /// <summary> /// 初期化処理. /// </summary> // --------------------------------------------------------------------------
void Init()
{
if (rigid == null) rigid = GetComponent();
}// -------------------------------------------------------------------------- /// <summary> /// 自動破壊コルーチン. /// </summary> /// <param name="time"> 破棄までの時間. </param> // --------------------------------------------------------------------------
IEnumerator AutoDestroy(float time)
{
yield return new WaitForSeconds(time);
Destroy(gameObject);
}// -------------------------------------------------------------------------- /// <summary> /// コライダーエンター. /// </summary> /// <param name="col"></param> // --------------------------------------------------------------------------
public void OnArrowCollisionEnter(Collision col)
{
//if (col.gameObject.tag == “Ground” || col.gameObject.tag == “Enemy”)
if (col.gameObject.tag == “Ground”)
{
if (isAttack == true)
{
Debug.Log(“Ground!!!!!” + col.gameObject.name);rigid.isKinematic = true;
rigid.velocity = Vector3.zero;
rigid.angularVelocity = Vector3.zero;isAttack = false;
Destroy(gameObject);
}
}
}// -------------------------------------------------------------------------- /// <summary> /// 敵にヒットした時の処理. /// </summary> // --------------------------------------------------------------------------
public void OnEnemyHit()
{
if (autoDestroyCor != null)
{
StopCoroutine(autoDestroyCor);
}
rigid.isKinematic = true;
rigid.velocity = Vector3.zero;
rigid.angularVelocity = Vector3.zero;isAttack = false;
Destroy(gameObject);
}
}
When the arrow hit the ground, the console window shows “Ground!!!!!”.
So Debug.Log(“Ground!!!!!” + col.gameObject.name); works well.
enter image description here
Could you give me some tips for this problem?
Thank you for reading this.
I checked “arrow” and “enemy” have a RigidBody component.
I checked “arrow” and “enemy” respectively are tagged “Arrow” and “Enemy”.