using System.Collections;
using UnityEngine;
using UnityEngine.AI;
public class BaseAi : MonoBehaviour
{
float _currentHeal;
NavMeshAgent _agent;
Coroutine _MoveTo;
Coroutine _TargetSearch;
float _speed;
[SerializeField] float _walkSpeed=5f;
Transform _target;
LayerMask _targetMask;
bool _IsAlive;
Animator _animator;
private void Start()
{
_IsAlive = true;
_agent = GetComponent<NavMeshAgent>();
_animator = GetComponent<Animator>();
_TargetSearch = StartCoroutine(TargetSearch());
}
IEnumerator TargetSearch() //там свой способ для поиска используй, это просто для примера
{
while (true)
{
Collider[] colliders = Physics.OverlapSphere(transform.position, 25f, _targetMask);
if (colliders.Length != 0)
{
_target = colliders[Random.Range(0, colliders.Length)].transform;
}
yield return new WaitForSeconds(0.5f);
}
}
void SearchOff()
{
StopCoroutine(_TargetSearch);
_TargetSearch= null;
}
void BrainOff()
{
StopCoroutine(_MoveTo);
_MoveTo = null;
}
private void Update()
{
if (_IsAlive)
{
if (_target == null && _TargetSearch == null) _TargetSearch = StartCoroutine(TargetSearch());
if (_target != null && _TargetSearch != null) SearchOff();
if (_target != null && _MoveTo == null) _MoveTo = StartCoroutine(WalkTo());
if (_target == null && _MoveTo != null) BrainOff();
_animator.SetFloat("MoveSpeed", _agent.speed); // переключать анимацию мы будем через скорость самого зомби
}
}
IEnumerator WalkTo()
{
while (true)
{
_agent.SetDestination(_target.position);
if (_agent.remainingDistance! > _agent.stoppingDistance) TryAttack();
if(_agent.remainingDistance>15f) yield return new WaitForSeconds(0.8f); //SetDestination ресурсоемкая команда
else yield return new WaitForSeconds(0.2f); //делаем бота более распоропнее, чем ближе он подходит 5 раз в секунду вероятно тож много
}
}
void TryAttack()
{
_agent.speed = 0f;
_animator.SetTrigger("Attack");
Invoke("RetrigetAttack", 0.5f); //отжатие триггера на атаку, лучше сделать через анимацию, а так надо поставить примерное время анимации удара
Collider[] colliders = Physics.OverlapSphere(transform.position+transform.up+transform.forward*0.5f, 1.5f, _targetMask);
foreach (Collider collider in colliders)
{
switch (collider.tag) // можно сделать проще повесить на все элементы скрипт Heals и брать только его
{
case "Player":
if (collider.TryGetComponent(out Mover btr)) //у меня тут свои скрипты будут
{
btr.TakeDamage(Random.Range(25, 35));
}
break;
case "Turret":
if (collider.TryGetComponent(out Turret turret))
{
turret.TakeDamage(Random.Range(20, 30));
}
break;
case "Base":
if (collider.TryGetComponent(out Base Mybase))
{
Mybase.TakeDamage(Random.Range(70, 90));
}
}
}
}
public void RetrigetAttack() //триггер его можну отдажть через анимацию или коррутину
{
_animator.ResetTrigger("Attack");
_agent.speed = _walkSpeed;
}
public void TakeDamage(float damage)
{
_currentHeal -= damage;
if (_currentHeal! > 0) Die();
}
void Die()
{
_IsAlive = false;
if(_TargetSearch!=null) SearchOff();
if(_MoveTo!=null)BrainOff();
_agent.enabled = false;
_animator.SetTrigger("Die");
}
}
void MoveToPlayer()
{
transform.position = Vector3.MoveTowards(transform.position, _playerPos.position, _speed * Time.deltaTime);
}
void MoveToPlayer()
{
agent.SetDestination(_playerPos.position);
}
using UnityEngine;
public class Player : MonoBehaviour
{
[Header("PlayerAnker")]
[SerializeField] Transform _armorPos;
[SerializeField] Transform _weaponPos;
[SerializeField] Transform _helmetPos;
ItemHolder _ItemBase;
[Header("inventory")]
Item _helmetItem;
Item _weaponItem;
Item _armorItem;
private void Start()
{
_ItemBase = GameObject.FindGameObjectWithTag("GameMaster").GetComponent<ItemHolder>();
NewSword();
}
void NewSword()
{
_weaponItem = _ItemBase._allITemList[0]; //<= ну условно у меня там есть метод для получение нужного меча
EquipItem(_weaponItem, _weaponPos);
}
void EquipItem(Item item,Transform pos)
{
item.ReOpenItem(pos);
}
}
_sprites:
- {fileID: 10913, guid: 0000000000000000f000000000000000, type: 0}
using UnityEngine;
public class Item : ScriptableObject
{
public enum ObjType
{
HeavyArmor, LightArmor, Swords, Stuffs
}
public int _id;
public string _name;
public ObjType _Objtype;
public Sprite[] _sprites;
public Sprite icon;
public virtual void ReOpenItem(Transform pos)
{
GameObject openObj =new GameObject();
openObj.transform.position = pos.position;
openObj.transform.name = _name;
for (int i=0; i< _sprites.Length; i++)
{
GameObject sonObj = new GameObject();
sonObj.transform.SetParent(openObj.transform);
sonObj.transform.localPosition = Vector2.zero; //?
sonObj.AddComponent<SpriteRenderer>().sprite = _sprites[i];
sonObj.transform.name = "Sprite " + (i + 1);
}
}
}
using UnityEngine;
using UnityEngine.UI;
public class Plus : MonoBehaviour
{
Text _text;
private void OnEnable()
{
_text = GetComponent<Text>();
}
private void Start()
{
_text.text = "Testing";
}
}
вот такую ошибку выдает?