Я занимаюсь защитой башни. Есть разные узлы, на которых стоит турель. Вы получаете этот GameObject с функцией Node.activeNode.GetTurret (). У каждого типа башни есть свой сценарий, поэтому у него свой класс. Я хочу изменить текст на переменную из скрипта текущей башни, но я не знаю, какой скрипт у текущей башни, поэтому мой скрипт выглядит так:
GameObject _turret = Node.activeNode.GetTurret();
if (_turret.TryGetComponent(out CrossbowScript crossbowScript))
{
statsText[0].SetText(crossbowScript.damage.ToString());
statsText[1].SetText(crossbowScript.fireRate.ToString());
statsText[2].SetText(crossbowScript.range.ToString());
statsText[3].SetText(crossbowScript.bulletPenetration.ToString());
return;
}
else if(_turret.TryGetComponent(out BlitzScript blitzScript))
{
statsText[0].SetText(blitzScript.damage.ToString());
statsText[1].SetText(blitzScript.fireRate.ToString());
statsText[2].SetText(blitzScript.range.ToString());
statsText[3].SetText(blitzScript.bulletPenetration.ToString());
return;
}
else if (_turret.TryGetComponent(out CannonScript cannonScript))
{
statsText[0].SetText(cannonScript.damage.ToString());
statsText[1].SetText(cannonScript.fireRate.ToString());
statsText[2].SetText(cannonScript.range.ToString());
statsText[3].SetText(cannonScript.bulletPenetration.ToString());
return;
}
Есть ли способ, чтобы Я могу использовать GetComponent в целом, так что мне не всегда приходится запрашивать для каждой башни, включен ли скрипт для него, а если нет, то смотреть дальше. Я подумал, что вы могли бы создать скрипт, который есть на каждой башне и всегда одинаковый, а затем возвращает тип скрипта башни, но я не знаю, как сделать функцию, которая возвращает в зависимости от другого типа. (Это просто идея, если у вас есть лучшая, пожалуйста, напишите это) Заранее спасибо за ваши отличные ответы
Вот полный CrossbowScript:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CrossbowScript : MonoBehaviour
{
private Transform target;
[Header("Attributes")]
public float damage = 10f;
public float fireRate = 1f;
public float range = 15f;
public float bulletPenetration = 5f;
private float fireCountdown = 0f;
public float turnSpeed = 10f;
[Header("Upgrading")]
public float upgradeDamage = 5f;
public float upgradeFireRate = 0.2f;
public float upgradeRange = 2f;
public float upgradeBulletPenetration = 1f;
[Header("Unity Setup Fields")]
public string enemyTag = "Enemy";
public Transform partToRotate;
public GameObject bulletPrefab;
public Transform firePoint;
public Animator anim;
void Start()
{
//UpdateTarget wird 2 mal pro sec ausgeführt
InvokeRepeating ("UpdateTarget", 0f, 0.5f);
}
void UpdateTarget () {
//Gegner Finden und den nähesten herausfinden
GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
float shortestDistance = Mathf.Infinity;
GameObject nearestEnemy = null;
foreach (GameObject enemy in enemies) {
float distanceToEnemy = Vector3.Distance (transform.position, enemy.transform.position);
if (distanceToEnemy < shortestDistance) {
shortestDistance = distanceToEnemy;
nearestEnemy = enemy;
}
}
if (nearestEnemy != null && shortestDistance <= range) {
target = nearestEnemy.transform;
}else{
target = null;
}
}
void Update()
{
if(anim.GetBool("IsShooting")) {
anim.SetBool("IsShooting", false);
}
if (target == null) {
return;
}
//Auf den Target schauen
Vector3 dir = target.position - transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Vector3 rotation = Quaternion.Lerp(partToRotate.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
partToRotate.rotation = Quaternion.Euler (0f, rotation.y, 0f);
if (fireCountdown <= 0f) {
Shoot();
fireCountdown = 1f / fireRate;
}
fireCountdown -= Time.deltaTime;
}
void Shoot () {
GameObject bulletGO = (GameObject)Instantiate (bulletPrefab, firePoint.position, firePoint.rotation);
//Neue Variable Bullet, Name der Variable arrow, arrowGo ist das Gameobject dass instanziert wurde, GetComponent<Bullet> man bekommt das Script Bullet
Bullet bullet = bulletGO.GetComponent<Bullet>();
anim.SetBool("IsShooting", true);
if(bullet != null) {
bullet.Seek(target, damage, bulletPenetration);
}
}
void OnDrawGizmosSelected () {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, range);
}
public void Upgrade(int attribute)
{
switch (attribute)
{
case 0:
damage += upgradeDamage;
break;
case 1:
fireRate += upgradeFireRate;
break;
case 2:
range += upgradeRange;
break;
case 3:
bulletPenetration += upgradeBulletPenetration;
break;
}
}
}
А вот полный CannonScript:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CannonScript : MonoBehaviour
{
private GameObject target;
[Header("Attributes")]
public float damage = 10f;
public float fireRate = 1f;
public float range = 15f;
public float bulletPenetration = 1f;
private float fireCountdown = 0f;
public float turnSpeed = 10f;
[Header("Upgrading")]
public float upgradeDamage = 5f;
public float upgradeFireRate = 0.2f;
public float upgradeRange = 2f;
public float upgradeBulletPenetration = 1f;
[Header("Unity Setup Fields")]
public string enemyTag = "Enemy";
public Transform partToRotate;
public GameObject bulletPrefab;
public Transform firePoint;
void Start()
{
//UpdateTarget wird 2 mal pro sec ausgeführt
InvokeRepeating ("UpdateTarget", 0f, 0.5f);
}
void UpdateTarget () {
//Gegner Finden und den nähesten herausfinden
GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
float shortestDistance = Mathf.Infinity;
GameObject nearestEnemy = null;
foreach (GameObject enemy in enemies) {
float distanceToEnemy = Vector3.Distance (transform.position, enemy.transform.position);
if (distanceToEnemy < shortestDistance) {
shortestDistance = distanceToEnemy;
nearestEnemy = enemy;
}
}
if (nearestEnemy != null && shortestDistance <= range) {
target = nearestEnemy;
}else{
target = null;
}
}
void Update()
{
if (target == null) {
return;
}
//Auf den Target schauen
Vector3 dir = target.transform.position - transform.position;
Quaternion lookRotation = Quaternion.LookRotation(dir);
Vector3 rotation = Quaternion.Lerp(partToRotate.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
partToRotate.rotation = Quaternion.Euler (0f, rotation.y, 0f);
if (fireCountdown <= 0f) {
Shoot();
fireCountdown = 1f / fireRate;
}
fireCountdown -= Time.deltaTime;
}
void Shoot () {
GameObject bulletGO = (GameObject)Instantiate (bulletPrefab, firePoint.position, firePoint.rotation);
//Neue Variable Bullet, Name der Variable arrow, arrowGo ist das Gameobject dass instanziert wurde, GetComponent<Bullet> man bekommt das Script Bullet
RockBullet bullet = bulletGO.GetComponent<RockBullet>();
if(bullet != null) {
bullet.Seek(target, damage, bulletPenetration);
}
}
void OnDrawGizmosSelected () {
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, range);
}
public void Upgrade(int attribute)
{
switch (attribute)
{
case 0:
damage += upgradeDamage;
break;
case 1:
fireRate += upgradeFireRate;
break;
case 2:
range += upgradeRange;
break;
case 3:
bulletPenetration += upgradeBulletPenetration;
break;
}
}
}
А вот функции nodeScript:
public GameObject turret;
public GameObject GetTurret()
{
return turret;
}
public void BuildTurret(GameObject turretToBuild)
{
if (turret != null){
//Upgrade Tower oder Zerstören
Debug.Log("Can't build there! - Feld für Upgrade oder so");
return;
}
turret = (GameObject)Instantiate(turretToBuild, transform.position, transform.rotation);
}