Einheit: Eine Referenz auf ein Objekt ist erforderlich, um Zugriff auf nicht-statische member - Ray cast GameObject
Mache ich eine RTS-Stil-Spiel und ich habe ein Fehler.
Ich bin versucht, senden Sie die aktuell ausgewählte Einheit (also das Objekt, das Skript ist auf) der Spielmacher FSM des Objektes in der raycast hit. Ich merkte, dass Sie nicht in gameobjects und verwandelt sich innerhalb von einer statischen Funktion, so habe ich versucht, rufen Sie eine andere Funktion verwenden, die Treffer und füllen Sie das gameobject variable.
Dies ist der Fehler:
Assets/Scripts/Unit.cs(57,41): error CS0120: An object reference is required to access non-static member `Unit.SetOurObject(UnityEngine.RaycastHit)'
Das Hauptproblem denke ich ist hier:
public static Vector3 GetDestination()
{
if (moveToDestination == Vector3.zero)
{
RaycastHit hit;
Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(r, out hit))
{
while (!passables.Contains(hit.transform.gameObject.name))
{
if (!Physics.Raycast(hit.transform.position, r.direction, out hit)) //point + r.direction * 0.1f
break;
}
//gameObject.GetComponent<NavMeshAgent>().SetDestination(hit.point);
//if (hit.transform != null){
//print (hit);
if (resources.Contains(hit.transform.gameObject.name)){
SetOurObject(hit);
//SelectedUnit.Value = GameObject.name;
//ResourceHit.Fsm.Event("startHit");
} else {
moveToDestination = hit.point;
}
//}
}
}
return moveToDestination;
}
public void SetOurObject(RaycastHit hitRay)
{
ourObject = hitRay.transform.gameObject;
PlayMakerFSM ourFSM = ourObject.GetComponent<PlayMakerFSM>();
FsmGameObject SelectedUnit = ourFSM.FsmVariables.GetFsmGameObject("SelectedUnit");
SelectedUnit.Value = new GameObject();
ourFSM.Fsm.Event("ResourceHit");
}
Und hier ist das ganze script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using HutongGames.PlayMaker;
public class Unit : MonoBehaviour {
public PlayMakerFSM ResourceHit;
public GameObject ourObject;
public bool selected = false;
private Color SelectedCol = new Color(0.114f, 0.22f, 0.039f, 1.0f);
private Color UnselectedCol = new Color(0.357f, 0.604f, 0.184f, 1.0f);
private bool selectedByClick = false;
private Vector3 moveToDest = Vector3.zero;
private static Vector3 moveToDestination = Vector3.zero;
private static List<string> passables = new List<string>() { "Floor" };
private static List<string> resources = new List<string>() { "Res_Wood" };
//Update is called once per frame
private void CleanUp()
{
if (!Input.GetMouseButtonUp(1))
moveToDestination = Vector3.zero;
}
private NavMeshAgent agent;
void Start() {
agent = GetComponent<NavMeshAgent>();
}
public static Vector3 GetDestination()
{
if (moveToDestination == Vector3.zero)
{
RaycastHit hit;
Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(r, out hit))
{
while (!passables.Contains(hit.transform.gameObject.name))
{
if (!Physics.Raycast(hit.transform.position, r.direction, out hit))
break;
}
if (resources.Contains(hit.transform.gameObject.name)){
SetOurObject(hit);
} else {
moveToDestination = hit.point;
}
}
}
return moveToDestination;
}
public void SetOurObject(RaycastHit hitRay)
{
ourObject = hitRay.transform.gameObject;
PlayMakerFSM ourFSM = ourObject.GetComponent<PlayMakerFSM>();
FsmGameObject SelectedUnit = ourFSM.FsmVariables.GetFsmGameObject("SelectedUnit");
SelectedUnit.Value = new GameObject();
ourFSM.Fsm.Event("ResourceHit");
}
void Update () {
CleanUp();
if (this.GetComponent<Renderer>().isVisible && Input.GetMouseButton(0))
{
if (!selectedByClick){
Vector3 camPos = Camera.main.WorldToScreenPoint(transform.position);
camPos.y = CameraOperator.InvertMouseY (camPos.y);
selected = CameraOperator.selection.Contains(camPos);
}
if (selected)
this.GetComponent<Renderer> ().material.color = UnselectedCol;
else
this.GetComponent<Renderer> ().material.color = SelectedCol;
}
if (selected && Input.GetMouseButtonUp(1))
{
Vector3 destination = GetDestination();
if (destination != Vector3.zero)
{
gameObject.GetComponent<NavMeshAgent>().SetDestination(destination); //all you need if you have unity pro
//moveToDest = destination;
//moveToDest.y += floorOffset;
}
}
}
private void OnMouseDown()
{
selectedByClick = true;
selected = true;
}
private void OnMouseUp()
{
if (selectedByClick)
selected = true;
selectedByClick = false;
}
}
}
Vielen Dank im Voraus! =)
- Verwenden Sie nicht die Einheit tag, um Fragen zu Unity3d game-engine. Es gibt unity3d-tag für, die.
- Entschuldigung dafür, ich wusste nicht,
Du musst angemeldet sein, um einen Kommentar abzugeben.
Obwohl Christos ist Recht
why
wirft er eine Ausnahme (die Sie versuchen, Zugriff auf eine Instanz-Methode, als ob es eine statische Methode), er fehlt ein detail.In Unity3D kann man nicht instanziieren (leicht) Klassen, implementieren von MonoBehaviour. Erstellen Sie Sie durch das anbringen einer Skript-Komponente zu bestehenden gameobjects und dann können Sie verweisen Sie im code.
Also um dies zu lösen, wenn Sie wollen, rufen Sie diese Methode, müssen Sie zunächst ein Verweis auf die beigefügte Skript-Komponente, die in der Szene und dann können Sie es tun.
Einfaches Beispiel, sagen wir, der Skript-Komponente Einheit verbunden ist, um den gleichen GameObject, verweisen Sie es so:
Aus der Fehlermeldung, die Sie haben, ist es klar, dass die Methode
SetOurObject(UnityEngine.RaycastHit)
ist nicht ein
static
Methode der KlasseUnit
.Daher müssen Sie zuerst erstellen Sie eine Instanz dieser Klasse und nach dieser Aufruf dieser Methode.
Dann könnten Sie rufen die Methode mit diesem Objekt.
SetOurObject
ist eine Methode, dieUnit
Klasse. Richtig? Wenn dem so ist, wie es zu sein scheint, und angesichts der Tatsache, dass nicht einstatic
Methode, die Sie verwenden können, es auf diese Weise:Static.SetOurObject(UnityEngine.RaycastHit)
, wie wir im Fall vonWriteLine
Methode derConsole
KlasseConsole.WriteLine
. Wir haben zuerst erstellen Sie eine Instanz der KlasseUnit
und rufen Sie dann auf dieses Objekt, diese Methode. Ist mehr klar jetzt?ClassName.Method()
. Es gibt kein Konzept der dynamischen Methode, wie weit ich bin bewusst. Also, wenn deine Frage ist, wenn Sie ändern, können dieGetDestination
ausstatic
nicht statisch, um eine Instanz-Methode, meine Antwort ist ja. Sie können dies tun, vorausgesetzt, dass zu Ihren Bedürfnissen passt.