mirror of
https://github.com/stride3d/stride.git
synced 2026-10-12 02:23:23 +00:00
Samples and templates: gameplay follows the time factor, camera and UI don't Timers, cooldowns, speeds and animation now use UpdateTime.WarpElapsed, so they stop when Factor is 0, like physics and particles already did. Camera, input and UI keep UpdateTime.Elapsed. The animation scripts also read UpdateTime instead of DrawTime, which is the clock the engine's own animation system uses. Removes the unused BasicCameraController from ThirdPersonPlatformer.
142 lines
4.2 KiB
C#
142 lines
4.2 KiB
C#
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
|
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
|
|
|
using System;
|
|
using System.Threading.Tasks;
|
|
using Stride.Core;
|
|
using Stride.Input;
|
|
using Stride.Engine;
|
|
|
|
namespace ParticlesSample
|
|
{
|
|
/// <summary>
|
|
/// A script which spawns a timed instance from a source prefab.
|
|
/// </summary>
|
|
public class PrefabInstance : AsyncScript
|
|
{
|
|
/// <summary>
|
|
/// Source to the prefab, selectable by the user
|
|
/// </summary>
|
|
[DataMember(10)]
|
|
[Display("Source")]
|
|
public Prefab SourcePrefab;
|
|
|
|
/// <summary>
|
|
/// Should the prefab follow the entity's transform component on change or not
|
|
/// </summary>
|
|
[DataMember(20)]
|
|
[Display("Following")]
|
|
public bool Following
|
|
{
|
|
get { return following; }
|
|
set { following = value; }
|
|
}
|
|
private bool following = true;
|
|
|
|
/// <summary>
|
|
/// How long before the prefab instance is deleted, selectable by the user
|
|
/// </summary>
|
|
[DataMember(30)]
|
|
[Display("Timeout")]
|
|
public float InstanceTimeout = 3f;
|
|
|
|
[DataMember(40)]
|
|
[Display("Trigger Time")]
|
|
public float TimeDelay { get; set; }
|
|
|
|
[DataMember(50)]
|
|
[Display("Animation")]
|
|
public AnimationComponent Animation { get; set; }
|
|
|
|
private bool canTrigger = true;
|
|
private double lastTime = 0;
|
|
|
|
public override async Task Execute()
|
|
{
|
|
while (Game.IsRunning)
|
|
{
|
|
await Script.NextFrame();
|
|
|
|
if (IsTriggered())
|
|
{
|
|
SpawnInstance();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected bool IsTriggered()
|
|
{
|
|
var time = Animation?.PlayingAnimations[0].CurrentTime.TotalSeconds ?? 0;
|
|
|
|
if (time < lastTime)
|
|
canTrigger = true;
|
|
|
|
var isTriggered = (canTrigger && TimeDelay <= time);
|
|
|
|
lastTime = time;
|
|
if (isTriggered)
|
|
canTrigger = false;
|
|
|
|
return isTriggered;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Will add a cloned entity from the prefab to the scene, wait for the specified time and delete it
|
|
/// </summary>
|
|
protected void SpawnInstance()
|
|
{
|
|
if (SourcePrefab == null)
|
|
return;
|
|
|
|
Func<Task> spawnTask = async () =>
|
|
{
|
|
// Clone
|
|
var spawnedEntities = SourcePrefab.Instantiate();
|
|
|
|
// Add
|
|
foreach (var prefabEntity in spawnedEntities)
|
|
{
|
|
if (Following)
|
|
{
|
|
Entity.AddChild(prefabEntity);
|
|
}
|
|
else
|
|
{
|
|
prefabEntity.Transform.UpdateLocalMatrix();
|
|
var worldMatrix = prefabEntity.Transform.LocalMatrix * Entity.Transform.WorldMatrix;
|
|
worldMatrix.Decompose(out prefabEntity.Transform.Scale, out prefabEntity.Transform.Rotation, out prefabEntity.Transform.Position);
|
|
|
|
SceneSystem.SceneInstance.RootScene.Entities.Add(prefabEntity);
|
|
}
|
|
}
|
|
|
|
// Countdown
|
|
var secondsCountdown = InstanceTimeout;
|
|
while (secondsCountdown > 0f)
|
|
{
|
|
await Script.NextFrame();
|
|
secondsCountdown -= (float)Game.UpdateTime.WarpElapsed.TotalSeconds;
|
|
}
|
|
|
|
// Remove
|
|
foreach (var clonedEntity in spawnedEntities)
|
|
{
|
|
if (Following)
|
|
{
|
|
Entity.RemoveChild(clonedEntity);
|
|
}
|
|
else
|
|
{
|
|
SceneSystem.SceneInstance.RootScene.Entities.Remove(clonedEntity);
|
|
}
|
|
}
|
|
|
|
// Cleanup
|
|
spawnedEntities.Clear();
|
|
};
|
|
|
|
Script.AddTask(spawnTask);
|
|
}
|
|
}
|
|
}
|