虚幻引擎的C#脚本插件 UnrealCS Demo指南
·
虚幻引擎C#插件现在已经开源,开发者可以使用C#语言来开发项目了。
源码地址:https://github.com/xiongfang/UnrealCS
文档地址:https://github.com/xiongfang/UnrealCS/wiki
示例项目地址:https://github.com/xiongfang/UnrealCS/wiki/Demonstration-project
这个示例是基于ThirdPerson 蓝图工程创建的,只做了一点点修改。
包含地图:
- Engine.umap (Persistent Level)
- UI.umap (sublevel1)
- ThirdPersonExampleMap.umap (sublevel2)
包含组件(用C#写的)
- Engine
- MainUI
- MyCharacter
- MyPlayerController
- LightFade
流程: 1.Engine.umap 包含Engine Actor,这个Actor包含Engine组件。Engine组件的生命周期存在于整个游戏的生命周期。 启动游戏后,在Engine.BeginPlay函数中,加载UI地图
/// <summary>
/// called on begin play
/// </summary>
void BeginPlay()
{
LogInfo("BeginPlay");
//Open UI Level
LogInfo("Open UI Level");
FLatentActionInfo Info = new FLatentActionInfo();
UGameplayStatics.LoadStreamLevel(this, "UI",true,false, Info);
}
2.UI.umap 包含UI Actor,这个Actor包含MainUI组件。这个组件处理UI事件。
/// <summary>
/// Main Scene UI
/// </summary>
public class MainUI:UnrealEngine.UMonoActorComponent
{
public TSubclassOf<UUserWidget> MainWidget;
APlayerController PC;
UUserWidget widget;
public static MainUI Instance;
public MainUI()
{
Instance = this;
}
/// <summary>
/// called on register
/// </summary>
void OnRegister()
{
Instance = this;
}
/// <summary>
/// called on unregister
/// </summary>
void OnUnRegister()
{
Instance = null;
}
/// <summary>
/// called on begin play
/// </summary>
void BeginPlay()
{
//Show UI
_Open();
}
/// <summary>
/// Called On End Play
/// </summary>
void OnDestroy()
{
Instance = null;
}
void Init()
{
if (widget != null)
return;
PC = UGameplayStatics.GetPlayerController(GetWorld(), 0);
widget = UWidgetBlueprintLibrary.Create(this, MainWidget, PC);
//bind start game button event
{
UButton BtnStart = widget.WidgetTree.FindWidget<UButton>("Button_Start");
FMulticastScriptDelegate OnClick = BtnStart.OnClicked;
OnClick.Add(this, "OnClickStart");
BtnStart.OnClicked = OnClick;
}
//bind quit game button event
{
UButton BtnStart = widget.WidgetTree.FindWidget<UButton>("Button_Quit");
FMulticastScriptDelegate OnClick = BtnStart.OnClicked;
OnClick.Add(this, "OnClickQuit");
BtnStart.OnClicked = OnClick;
}
}
/// <summary>
/// This Must be Public for export to blueprint
/// </summary>
public void OnClickStart()
{
LogInfo("ClickStart");
UGameplayStatics.LoadStreamLevel(this, "ThirdPersonExampleMap", true, true, new FLatentActionInfo());
ULevelStreaming LvStreaming = UGameplayStatics.GetStreamingLevel(this, "ThirdPersonExampleMap");
FMulticastScriptDelegate Del = LvStreaming.OnLevelLoaded;
Del.Add(Engine.Instance, "OnThirdPersonExampleMapShown");
LvStreaming.OnLevelShown = Del;
//Close UI
_Close();
//Unload UI Level
UGameplayStatics.UnloadStreamLevel(this, "UI", new FLatentActionInfo());
}
/// <summary>
/// This Must be Public for export to blueprint
/// </summary>
public void OnClickQuit()
{
LogInfo("OnClickQuit");
_Close();
UKismetSystemLibrary.QuitGame(GetWorld(), PC, EQuitPreference.Quit);
}
void _Close()
{
if (widget != null)
{
widget.RemoveFromParent();
}
PC.bShowMouseCursor = false;
UWidgetBlueprintLibrary.SetInputMode_GameOnly(PC);
}
void _Open()
{
if (widget == null)
{
Init();
}
widget.AddToViewport();
PC.bShowMouseCursor = true;
UWidgetBlueprintLibrary.SetInputMode_UIOnlyEx(PC, widget);
}
}
3.点击开始游戏按钮,加载ThirdPersonExampleMap地图,在MyCharacter组件的BeginPlay方法中,给角色创建了武器和盾牌
public class MyCharacter:UMonoActorComponent
{
public TSubclassOf<AStaticMeshActor> SwordPrefab;
public TSubclassOf<AStaticMeshActor> ShieldPrefab;
void BeginPlay()
{
//Create Shield And Sword
ACharacter Char = Cast<ACharacter>(this.GetOwner());
USkeletalMeshComponent skeletalMesh = Char.Mesh;
AActor weapon = GetWorld().SpawnActor(SwordPrefab, new FVector(), new FRotator());
weapon.K2_AttachToComponent(skeletalMesh, "hand_rSocket", EAttachmentRule.SnapToTarget, EAttachmentRule.SnapToTarget, EAttachmentRule.SnapToTarget, true);
AActor shield = GetWorld().SpawnActor(ShieldPrefab, new FVector(), new FRotator());
shield.K2_AttachToComponent(skeletalMesh, "lowerarm_lSocket", EAttachmentRule.SnapToTarget, EAttachmentRule.SnapToTarget, EAttachmentRule.SnapToTarget, true);
}
void Tick(float DeltaTime)
{
//UKismetSystemLibrary.DrawDebugString(this, new FVector(0, 0, 0), "wsad to move,j attack", GetOwner(),FLinearColor.Red);
}
}
4.在MyPlayerController组件的Tick方法中,监测玩家是否按下J键,如果按下了J键,则使用技能
技能的表现包括:
- 禁用玩家输入
- 播放一个刀光
- 播放剑的残影特效
- 播放空间扭曲特效
- 播放相机震动效果
/// <summary>
/// Called Every Frame
/// </summary>
/// <param name="DeltaTime"></param>
void Tick(float DeltaTime)
{
if (Target == null)
return;
if(OwnerPC.WasInputKeyJustPressed(MakeKey("J")) && !_is_skill_using)
{
LogInfo("Key J Down");
// Play Animation
_skill_time_length = Target.Mesh.GetAnimInstance().Montage_Play(Montage);
_skill_timer = 0.0f;
_is_skill_using = true;
//Disable Input
Target.DisableInput(OwnerPC);
//Attack Light
GetWorld().SpawnActor(AttackLight, Target.GetTransform().TransformPosition(FVector.ForwardVector * 300), Target.K2_GetActorRotation());
//Ghost
PS_SwordGhost= UGameplayStatics.SpawnEmitterAttached(PS_SwordGhostPreafab, Target.Mesh, "hand_rSocket", FVector.ZeroVector, FRotator.ZeroRotator, EAttachLocation.SnapToTarget);
//PS_HeatDistort
UGameplayStatics.SpawnEmitterAtLocation(this, PS_HeatDistort, Target.GetTransform().TransformPosition(FVector.ForwardVector * 300), Target.K2_GetActorRotation());
//Shake
UGameplayStatics.PlayWorldCameraShake(this, ShakePrefab, Target.K2_GetActorLocation(), shake_inner_radius, shake_outer_radius);
}
//Update Skill
if(_is_skill_using)
{
_skill_timer += DeltaTime;
if(_skill_timer>_skill_time_length)
{
_is_skill_using = false;
//Destroy Particle System
PS_SwordGhost.K2_DestroyComponent(PS_SwordGhost);
//Enable Input
Target.EnableInput(OwnerPC);
return;
}
//Apply Force
if(_skill_timer<_skill_time_length-0.5f)
{
FHitResult Hit;
Target.K2_AddActorWorldOffset(Target.GetTransform().TransformVector(FVector.ForwardVector) * 300 * DeltaTime, false, out Hit, false);
}
}
}
5.在刀光效果的更新组件中(LightFade),让光源产生一个闪光效果
/// <summary>
/// Fade Light In And Out
/// </summary>
public class LightFade:UnrealEngine.UMonoActorComponent
{
float _fadeInTime = 0.3f;
float _fadeOutTime = 0.3f;
float _timer;
public float intensity = 500000;
UPointLightComponent lightCom;
void BeginPlay()
{
lightCom = GetOwner().GetComponentByClass<UPointLightComponent>();
}
void Tick(float DeltaTime)
{
_timer += DeltaTime;
if(_timer< _fadeInTime)
{
lightCom.Intensity = _timer / _fadeInTime * intensity;
}
else if(_timer < _fadeInTime+ _fadeOutTime)
{
lightCom.Intensity = (_timer- _fadeInTime) / _fadeOutTime * intensity;
}
else
{
//Destroy Light
GetOwner().Destroy();
}
}
}
更多推荐
已为社区贡献2条内容
所有评论(0)