Questa pagina spiega i concetti di programmazione del gameplay di Unreal Engine (UE) per gli utenti di Unity. Le spiegazioni seguenti presuppongono che l'utente abbia familiarità con Unity C# e intenda apprendere l'utilizzo di UE C++ e Blueprint.
Gli esempi che seguono mostrano alcuni casi d'uso comuni nella programmazione del gameplay in Unity C# e come poter implementare le stesse funzionalità in UE.
Creazione di istanze di GameObject/Spawning Actor
In Unity, utilizza la funzione Instantiate per creare nuove istanze di oggetti. Questa funzione prende qualsiasi tipo di UnityEngine.Object (GameObject, MonoBehaviour, ecc.) e ne crea una copia.
public GameObject EnemyPrefab;
public Vector3 SpawnPosition;
public Quaternion SpawnRotation;
void Start()
{
GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation);
NewGO.name = "MyNewGameObject";
}UE offre due funzioni diverse per istanziare gli oggetti:
NewObjectcrea nuovi tipi diUObject.SpawnActorgenera tipi diAActor.
UObject e NewObject
La sottoclasse di UObject in UE è simile alla sottoclasse di ScriptableObject in Unity. Sono utili per le classi di gameplay che non hanno bisogno di generare nel mondo o di avere componenti collegati, come accade per gli attori.
In Unity, se hai creato una sottoclasse di ScriptableObject, puoi istanziarla in questo modo:
MyScriptableObject NewSO = ScriptableObject.CreateInstance<MyScriptableObject>();In UE, se crei una sottoclasse di UObject, puoi istanziarla in questo modo:
UMyObject* NewObj = NewObject<UMyObject>();AActor e SpawnActor
Puoi generare attori usando il metodo SpawnActor su un oggetto Mondo (UWorld in C++). Alcuni UObject e tutti gli attori hanno un metodo GetWorld per trovare l'oggetto Mondo.
Nell'esempio seguente, usiamo questi metodi con i parametri di generazione di un attore esistente per emulare la funzionalità del metodo Instantiate di Unity.
Esempio
Di seguito trovi un esempio di sottoclasse AActor, AMyActor. Il costruttore predefinito inizializza int32 e USphereComponent*.
Presta attenzione all'uso della funzione CreateDefaultSubobject. Questa funzione crea componenti e assegna loro proprietà predefinite. I sotto-oggetti creati con questa funzione fungono da modello predefinito, pertanto è possibile modificarli in una sottoclasse o in una Blueprint.
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
int32 MyIntProp;
UPROPERTY()
USphereComponent* MyCollisionComp;
In questo modo, viene creato un clone di un AMyActor, comprese tutte le variabili membro, UPROPERTY e i componenti.
AMyActor* CreateCloneOfMyActor(AMyActor* ExistingActor, FVector SpawnLocation, FRotator SpawnRotation)
{
UWorld* World = ExistingActor->GetWorld();
FActorSpawnParameters SpawnParams;
SpawnParams.Template = ExistingActor;
World->SpawnActor<AMyActor>(ExistingActor->GetClass(), SpawnLocation, SpawnRotation, SpawnParams);
}Esecuzione del casting (conversione di tipo)
In questo caso, si determina un componente che si ha la certezza di possedere, poi se ne effettua il casting su un tipo specifico e si esegue un'operazione in modo condizionale.
Unity
Collider collider = gameObject.GetComponent<Collider>;
SphereCollider sphereCollider = collider as SphereCollider;
if (sphereCollider != null)
{
// ...
}UE C++
UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());
USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);
if (SphereCollider != nullptr)
{
// ...
}Blueprint
Puoi effettuare un casting in Blueprint utilizzando un nodo Converti in. Per maggiori dettagli, vedi Casting Quick Start Guide (Guida introduttiva al casting).
Distruzione del GameObject/Actor
Distruzione del GameObject/Actor (con un ritardo di 1 secondo)
Disabilitazione dei GameObject/Actor
Unity C# C# | UE C++ C++ | Blueprint |
Accesso al GameObject/Actor da un componente
Unity C# C++ | UE C++ C++ | Blueprint |
Accesso a un Component dal GameObject/Actor
Unity
MyComponent MyComp = gameObject.GetComponent<MyComponent>();UE C++
UMyComponent* MyComp = MyActor->FindComponentByClass<UMyComponent>();Blueprint
Trovare i GameObject/Actor
Unity
// Find GameObject by name
GameObject MyGO = GameObject.Find("MyNamedGameObject");
// Find Objects by type
MyComponent[] Components = Object.FindObjectsOfType(typeof(MyComponent)) as MyComponent[];
foreach (MyComponent Component in Components)
{
// ...
}
UE C++
// Find UObjects by type
for (TObjectIterator<UMyObject> It; It; ++it)
{
UMyObject* MyObject = *It;
// ...
}
// Find Actor by name (also works on UObjects)
AActor* MyActor = FindObject<AActor>(nullptr, TEXT("MyNamedActor"));
Blueprint
Aggiungere tag a GameObjects/attori
Unity
MyGameObject.tag = "MyTag";UE C++
// Actors can have multiple tags
MyActor.Tags.AddUnique(TEXT("MyTag"));Blueprint
Aggiungere tag a MonoBehaviours/ActorComponents
Unity
// This changes the tag on the GameObject it is attached to
MyComponent.tag = "MyTag";UE C++
// Components have their own array of tags
MyComponent.ComponentTags.AddUnique(TEXT("MyTag"));Comparazione dei tag su GameObjects/attori e MonoBehaviours/ActorComponents
Unity
if (MyGameObject.CompareTag("MyTag"))
{
// ...
}
// Checks the tag on the GameObject it is attached to
if (MyComponent.CompareTag("MyTag"))
{
// ...
}UE C++
// Checks if an Actor has this tag
if (MyActor->ActorHasTag(FName(TEXT("MyTag"))))
{
// ...
}Blueprint
UE C++
// Checks if an ActorComponent has this tag
if (MyComponent->ComponentHasTag(FName(TEXT("MyTag"))))
{
// ...
}Blueprint
Fisica: confronto tra RigidBody e Componente primitivo
In Unity, per attribuire a un GameObject delle caratteristiche fisiche, si collega un componente RigidBody.
In UE, qualsiasi componente primitivo (UPrimitiveComponent in C++) può rappresentare un oggetto fisico. Alcuni componenti primitivi comuni sono:
Componenti della forma (
USphereComponent,UCapsuleComponent, ecc.)Componente Static Mesh
Componenti Skeletal Mesh
A differenza di Unity, che separa le responsabilità della collisione e delle visualizzazioni in componenti distinti, UE unisce i concetti di "potenzialmente fisico" e "potenzialmente visibile" in un unico componente primitivo. Qualsiasi componente con geometria nel mondo che può essere renderizzato o con cui è possibile interagire fisicamente costituisce una sottoclasse di UPrimitiveComponent.
I canali di collisione sono l'equivalente UE dei livelli in Unity. Per sapere di più, vedi Collision Filtering (Filtro anticollisione).
Confronto tra RayCast e RayTrace
Unity
GameObject FindGOCameraIsLookingAt()
{
Vector3 Start = Camera.main.transform.position;
Vector3 Direction = Camera.main.transform.forward;
float Distance = 100.0f;
int LayerBitMask = 1 << LayerMask.NameToLayer("Pawn");
RaycastHit Hit;
bool bHit = Physics.Raycast(Start, Direction, out Hit, Distance, LayerBitMask);
UE C++
APawn* AMyPlayerController::FindPawnCameraIsLookingAt()
{
// You can use this to customize various properties about the trace
FCollisionQueryParams Params;
// Ignore the player's pawn
Params.AddIgnoredActor(GetPawn());
// The hit result gets populated by the line trace
FHitResult Hit;
Blueprint
Trigger Volume
Unity
public class MyComponent : MonoBehaviour
{
void Start()
{
collider.isTrigger = true;
}
void OnTriggerEnter(Collider Other)
{
// ...
}
UE C++
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
// My trigger component
UPROPERTY()
UPrimitiveComponent* Trigger;
AMyActor()
Blueprint
Per sapere di più su come impostare le risposte alle collisioni, vedi Collisione.
Cinematica dei Rigidbody
Unity
public class MyComponent : MonoBehaviour
{
void Start()
{
rigidbody.isKinematic = true;
rigidbody.velocity = transform.forward * 10.0f;
}
}UE C++
UCLASS()
class AMyActor : public AActor
{
GENERATED_BODY()
UPROPERTY()
UPrimitiveComponent* PhysicalComp;
AMyActor()
{
Eventi di input
Unity
public class MyPlayerController : MonoBehaviour
{
void Update()
{
if (Input.GetButtonDown("Fire"))
{
// ...
}
float Horiz = Input.GetAxis("Horizontal");
float Vert = Input.GetAxis("Vertical");
UE C++
UCLASS()
class AMyPlayerController : public APlayerController
{
GENERATED_BODY()
void SetupInputComponent()
{
Super::SetupInputComponent();
InputComponent->BindAction("Fire", IE_Pressed, this, &AMyPlayerController::HandleFireInputEvent);
Blueprint
Le proprietà di input potrebbero avere questo aspetto nelle Impostazioni progetto:
Per sapere di più su come impostare l'input per il progetto UE, vedi Input.
Per approfondire
Per sapere di più su questi argomenti, ti consigliamo di consultare le sezioni seguenti:
Gameplay Framework (Struttura di gioco): copre i sistemi di gioco principali, ad esempio la modalità di gioco, lo stato del giocatore, i controller, le pedine, le visuali e altro ancora.
Gameplay Architecture (Architettura del gameplay): riferimento per creare e implementare classi di gameplay.
Gameplay Tutorials (Tutorial sul gameplay): tutorial per ricreare elementi comuni del gameplay.