Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

## Unreleased

Built with [Unity 2020.2](https://github.com/freezy/VisualPinball.Engine/pull/255).
Built with Unity 2020.3.

### Added
- Remove Hybrid Renderer ([#316](https://github.com/freezy/VisualPinball.Engine/pull/316)).
- Create and use Unity assets when importing ([#320](https://github.com/freezy/VisualPinball.Engine/pull/302)).
- Native support for nFozzy flipper physics ([#305](https://github.com/freezy/VisualPinball.Engine/pull/305)).
- Automated camera clipping ([#304](https://github.com/freezy/VisualPinball.Engine/pull/304/files)).
- DMD and segment display support ([Documentation](https://docs.visualpinball.org/creators-guide/manual/displays.html)).
Expand Down
Binary file modified VisualPinball.Engine.Test/Fixtures~/PlungerTest.vpx
Binary file not shown.
7 changes: 1 addition & 6 deletions VisualPinball.Engine/VPT/PbrMaterial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ public class PbrMaterial
public bool HasNormalMap => NormalMap != null;
public BlendMode MapBlendMode => GetBlendMode();

public readonly bool VertexLerpWithUvEnabled;

public Color Color => _material?.BaseColor.WithAlpha(255) ?? new Color(0xffffffff, ColorFormat.Bgr);
public bool IsMetal => _material?.IsMetal ?? false;
public bool IsOpacityActive => _material?.IsOpacityActive ?? false;
Expand All @@ -55,19 +53,17 @@ public class PbrMaterial

private readonly Material _material;

public PbrMaterial(Material material = null, Texture map = null, Texture normalMap = null, Texture envMap = null, bool vertexLerp = false, string id = null)
public PbrMaterial(Material material = null, Texture map = null, Texture normalMap = null, Texture envMap = null, string id = null)
{
_material = material;
Map = map;
NormalMap = normalMap;
EnvMap = envMap;
VertexLerpWithUvEnabled = vertexLerp;
Id = id ?? string.Join("-", new[] {
_material?.Name.ToNormalizedName() ?? NameNoMaterial,
Map?.Name.ToNormalizedName() ?? NameNoMap,
NormalMap?.Name.ToNormalizedName() ?? NameNoNormalMap,
EnvMap?.Name.ToNormalizedName() ?? NameNoEnvMap,
vertexLerp ? "skinned" : NameNoLerp
}
.Reverse()
.SkipWhile(s => s.StartsWith("__no_"))
Expand Down Expand Up @@ -127,7 +123,6 @@ public override string ToString()
sb.AppendLine($"Map {Map?.ToString() ?? "none"}".Trim());
sb.AppendLine($"MapBlendMode {MapBlendMode}");
sb.AppendLine($"NormalMap {NormalMap?.ToString() ?? "none"}".Trim());
sb.AppendLine($"Skinned? {VertexLerpWithUvEnabled}");

return sb.ToString();
}
Expand Down
6 changes: 3 additions & 3 deletions VisualPinball.Engine/VPT/Plunger/PlungerMeshGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public RenderObject GetRenderObject(Table.Table table, string id, Origin origin,
return new RenderObject(
id,
asRightHanded ? flatMesh.Transform(Matrix3D.RightHanded) : flatMesh,
new PbrMaterial(id: $"__plunger_flat_{_data.Name}", material: mat, map: tex, vertexLerp: true),
new PbrMaterial(id: $"__plunger_flat_{_data.Name}", material: mat, map: tex),
true
);
case Rod:
Expand All @@ -86,7 +86,7 @@ public RenderObject GetRenderObject(Table.Table table, string id, Origin origin,
return new RenderObject(
id,
asRightHanded ? rodMesh.Transform(Matrix3D.RightHanded) : rodMesh,
new PbrMaterial(id: $"__plunger_rod_{_data.Name}", material: mat, map: tex, vertexLerp: true),
new PbrMaterial(id: $"__plunger_rod_{_data.Name}", material: mat, map: tex),
true
);
case Spring:
Expand All @@ -95,7 +95,7 @@ public RenderObject GetRenderObject(Table.Table table, string id, Origin origin,
return new RenderObject(
id,
asRightHanded ? springMesh.Transform(Matrix3D.RightHanded) : springMesh,
new PbrMaterial(id: $"__plunger_spring_{_data.Name}", material: mat, map: tex, vertexLerp: true),
new PbrMaterial(id: $"__plunger_spring_{_data.Name}", material: mat, map: tex),
true
);
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Transform:
m_GameObject: {fileID: 8289283333368007096}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0.05, y: 0.05, z: 0.05}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ This camera can be moved [using Unity's gizmos](https://docs.unity3d.com/Manual/
> [!TIP]
> A quick way to fix the game camera is to align it with the scene view camera. To do that, select the camera in the hierarchy, then click on the *GameObject* menu and select *Align with view*.

One last thing we need to do before playing is enable version 2 of the [Hybrid Renderer](https://docs.unity3d.com/Packages/com.unity.rendering.hybrid@0.10/manual/index.html) we're using. Go to *Edit -> Project Settings*, select *Player* on the left, open the *Other Settings* tab, scroll down a bit on the right and add `ENABLE_HYBRID_RENDERER_V2` under *Script Define Symbols*.

![Enable hybrid renderer](unity-settings-hybridv2.png)

Then click on *Apply* and close the window.

Let's start the game by clicking on the play button. This will run your scene. Test that the shift keys move the flippers. `ENTER` will launch a ball. If you expand *Table1* in the hierarchy and select the *Trough*, you can watch its status in the inspector in real time. Cool!

You can also right-click on the scene view tab and select *Maximize*.
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ namespace VisualPinball.Unity.Test
{
public class TroughTests
{

#if !WRITE_VP106 && !WRITE_VP107

[Test]
public void ShouldWriteImportedTroughData()
{
Expand All @@ -40,5 +43,7 @@ public void ShouldWriteImportedTroughData()
File.Delete(tmpFileName);
Object.DestroyImmediate(go);
}

#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,24 +108,7 @@ public static void ApplyToUnityMesh(this Mesh vpMesh, UnityEngine.Mesh mesh)
mesh.triangles = vpMesh.Indices;

// animation
if (vpMesh.AnimationFrames.Count == 1) {

// if there's only one frame, we assume a linear interpolation and just
// add it in form of UV sets. we then have a shader that interpolates
// the mesh.

var deltaVertices = new Vector3[vpMesh.Vertices.Length];
var deltaNormals = new Vector3[vpMesh.Vertices.Length];

var blendVertices = vpMesh.AnimationFrames[0];
for (var i = 0; i < vpMesh.Vertices.Length; i++) {
deltaVertices[i] = blendVertices[i].ToUnityVector3() - vertices[i];
deltaNormals[i] = blendVertices[i].ToUnityNormalVector3() - normals[i];
}
mesh.SetUVs(Mesh.AnimationUVChannelVertices, deltaVertices);
mesh.SetUVs(Mesh.AnimationUVChannelNormals, deltaNormals);

} else if (vpMesh.AnimationFrames.Count > 0) {
if (vpMesh.AnimationFrames.Count > 0) {

var deltaWeight = 1f / vpMesh.AnimationFrames.Count;
var deltaVertices = new Vector3[vpMesh.Vertices.Length];
Expand Down
40 changes: 37 additions & 3 deletions VisualPinball.Unity/VisualPinball.Unity/Game/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class Player : MonoBehaviour
public TableApi TableApi { get; private set; }

// shortcuts
public Matrix4x4 TableToWorld => GetComponentInChildren<TablePlayfieldAuthoring>().transform.localToWorldMatrix;
public GameObject Playfield => GetComponentInChildren<TablePlayfieldAuthoring>().gameObject;

[NonSerialized]
public IGamelogicEngine GamelogicEngine;
Expand All @@ -73,6 +73,15 @@ public class Player : MonoBehaviour
private readonly Dictionary<Entity, IApiSlingshot> _slingshots = new Dictionary<Entity, IApiSlingshot>();

internal readonly Dictionary<Entity, Flipper> Flippers = new Dictionary<Entity, Flipper>();
internal readonly Dictionary<Entity, Transform> FlipperTransforms = new Dictionary<Entity, Transform>();
internal readonly Dictionary<Entity, Transform> BumperSkirtTransforms = new Dictionary<Entity, Transform>();
internal readonly Dictionary<Entity, Transform> BumperRingTransforms = new Dictionary<Entity, Transform>();
internal readonly Dictionary<Entity, Transform> GateWireTransforms = new Dictionary<Entity, Transform>();
internal readonly Dictionary<Entity, Transform> SpinnerPlateTransforms = new Dictionary<Entity, Transform>();
internal readonly Dictionary<Entity, Transform> TriggerTransforms = new Dictionary<Entity, Transform>();
internal readonly Dictionary<Entity, SkinnedMeshRenderer[]> PlungerSkinnedMeshRenderers = new Dictionary<Entity, SkinnedMeshRenderer[]>();
internal readonly Dictionary<Entity, GameObject> Balls = new Dictionary<Entity, GameObject>();


internal IEnumerable<IApiColliderGenerator> ColliderGenerators => _colliderGenerators;

Expand Down Expand Up @@ -124,7 +133,7 @@ private void Awake()

Table = tableComponent.Table; //tableComponent.CreateTable(tableComponent.Data);
_tableContainer = tableComponent.TableContainer;
BallManager = new BallManager(Table, TableToWorld);
BallManager = new BallManager(Table, this);
_inputManager = new InputManager();
_inputManager.Enable(HandleInput);

Expand Down Expand Up @@ -196,6 +205,15 @@ public void RegisterBumper(Bumper bumper, Entity entity, Entity parentEntity, Ga
_switchPlayer.RegisterSwitch(bumper, bumperApi);
_coilPlayer.RegisterCoil(bumper, bumperApi);
_wirePlayer.RegisterWire(bumper, bumperApi);

var ringAnimationAuth = go.GetComponentInChildren<BumperRingAnimationAuthoring>();
if (ringAnimationAuth) {
BumperRingTransforms[entity] = ringAnimationAuth.gameObject.transform;
}
var skirtAnimationAuth = go.GetComponentInChildren<BumperSkirtAnimationAuthoring>();
if (skirtAnimationAuth) {
BumperSkirtTransforms[entity] = skirtAnimationAuth.gameObject.transform;
}
}

public void RegisterFlipper(Flipper flipper, Entity entity, Entity parentEntity, GameObject go)
Expand All @@ -219,6 +237,8 @@ public void RegisterFlipper(Flipper flipper, Entity entity, Entity parentEntity,
if (EngineProvider<IDebugUI>.Exists) {
EngineProvider<IDebugUI>.Get().OnRegisterFlipper(entity, flipper.Name);
}

FlipperTransforms[entity] = go.transform;
}

public void RegisterGate(Gate gate, Entity entity, Entity parentEntity, GameObject go)
Expand All @@ -234,6 +254,11 @@ public void RegisterGate(Gate gate, Entity entity, Entity parentEntity, GameObje
}
_rotatables[entity] = gateApi;
_switchPlayer.RegisterSwitch(gate, gateApi);

var wireAnimAuthoring = go.GetComponentInChildren<GateWireAnimationAuthoring>();
if (wireAnimAuthoring) {
GateWireTransforms[entity] = wireAnimAuthoring.gameObject.transform;
}
}

public void RegisterHitTarget(HitTarget hitTarget, Entity entity, Entity parentEntity, GameObject go)
Expand Down Expand Up @@ -276,7 +301,7 @@ public void RegisterLamp(Light lamp, GameObject go)
_wirePlayer.RegisterWire(lamp, lightApi);
}

public void RegisterPlunger(Plunger plunger, Entity entity, Entity parentEntity, InputActionReference actionRef)
public void RegisterPlunger(Plunger plunger, Entity entity, Entity parentEntity, InputActionReference actionRef, GameObject go)
{
var plungerApi = new PlungerApi(plunger, entity, parentEntity, this);
TableApi.Plungers[plunger.Name] = plungerApi;
Expand All @@ -291,6 +316,8 @@ public void RegisterPlunger(Plunger plunger, Entity entity, Entity parentEntity,
actionRef.action.performed += plungerApi.OnAnalogPlunge;
_actions.Add((actionRef.action, plungerApi.OnAnalogPlunge));
}

PlungerSkinnedMeshRenderers[entity] = go.GetComponentsInChildren<SkinnedMeshRenderer>();
}

public void RegisterPrimitive(Primitive primitive, Entity entity, Entity parentEntity, GameObject go)
Expand Down Expand Up @@ -358,6 +385,11 @@ public void RegisterSpinner(Spinner spinner, Entity entity, Entity parentEntity,
_spinnables[entity] = spinnerApi;
_rotatables[entity] = spinnerApi;
_switchPlayer.RegisterSwitch(spinner, spinnerApi);

var plateAnimAuthoring = go.GetComponentInChildren<SpinnerPlateAnimationAuthoring>();
if (plateAnimAuthoring) {
SpinnerPlateTransforms[entity] = plateAnimAuthoring.gameObject.transform;
}
}

public void RegisterTrigger(Trigger trigger, Entity entity, Entity parentEntity, GameObject go)
Expand All @@ -372,6 +404,8 @@ public void RegisterTrigger(Trigger trigger, Entity entity, Entity parentEntity,
_hittables[entity] = triggerApi;
}
_switchPlayer.RegisterSwitch(trigger, triggerApi);

TriggerTransforms[entity] = go.transform;
}

public void RegisterTrigger(Trigger trigger, Entity entity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ public void SetAnimationAuthoring<T>(string name) where T : Component, IItemAnim
public IConvertedItem AddConvertToEntity(bool componentsAdded)
{
if (!componentsAdded) {
_gameObject.AddComponent<ConvertToEntity>();
var cte = _gameObject.AddComponent<ConvertToEntity>();
cte.ConversionMode = ConvertToEntity.Mode.ConvertAndInjectGameObject;
}

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ protected override void OnUpdate()
switch (coll.Type) {
case ColliderType.Bumper: {
var bumperStaticData = GetComponent<BumperStaticData>(coll.Entity);
var ringData = GetComponent<BumperRingAnimationData>(bumperStaticData.RingEntity);
var skirtData = GetComponent<BumperSkirtAnimationData>(bumperStaticData.SkirtEntity);
var ringData = GetComponent<BumperRingAnimationData>(coll.Entity);
var skirtData = GetComponent<BumperSkirtAnimationData>(coll.Entity);
BumperCollider.Collide(ref ballData, ref events, ref collEvent, ref ringData, ref skirtData,
in ballEntity, in coll, bumperStaticData, ref random);
SetComponent(bumperStaticData.RingEntity, ringData);
SetComponent(bumperStaticData.SkirtEntity, skirtData);
SetComponent(coll.Entity, ringData);
SetComponent(coll.Entity, skirtData);
break;
}

Expand All @@ -120,12 +120,12 @@ protected override void OnUpdate()

case ColliderType.Gate: {
var gateStaticData = GetComponent<GateStaticData>(coll.Entity);
var gateMovementData = GetComponent<GateMovementData>(gateStaticData.WireEntity);
var gateMovementData = GetComponent<GateMovementData>(coll.Entity);
GateCollider.Collide(
ref ballData, ref collEvent, ref gateMovementData, ref events,
in ballEntity, in coll, in gateStaticData
);
SetComponent(gateStaticData.WireEntity, gateMovementData);
SetComponent(coll.Entity, gateMovementData);
break;
}

Expand All @@ -149,12 +149,12 @@ protected override void OnUpdate()

case ColliderType.Spinner: {
var spinnerStaticData = GetComponent<SpinnerStaticData>(coll.Entity);
var spinnerMovementData = GetComponent<SpinnerMovementData>(spinnerStaticData.PlateEntity);
var spinnerMovementData = GetComponent<SpinnerMovementData>(coll.Entity);
SpinnerCollider.Collide(
in ballData, ref collEvent, ref spinnerMovementData,
in spinnerStaticData
);
SetComponent(spinnerStaticData.PlateEntity, spinnerMovementData);
SetComponent(coll.Entity, spinnerMovementData);
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ public void Init(TableAuthoring tableAuthoring, BallManager ballManager)
_worldToLocal = transform.worldToLocalMatrix;
}

public void BallCreate(in float3 worldPos, in float3 localPos,
public void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos,
in float3 localVel, in float scale, in float mass, in float radius, in Entity kickerRef)
{
_ballManager.CreateEntity(in worldPos, in localPos, in localVel,scale * radius * 2,
_ballManager.CreateEntity(ballGo, id, in worldPos, in localPos, in localVel,scale * radius * 2,
in mass, in radius, in kickerRef);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using VisualPinball.Engine.Common;

namespace VisualPinball.Unity
Expand All @@ -39,14 +40,16 @@ public interface IPhysicsEngine : IEngine
/// <summary>
/// Create a new ball and returns its entity.
/// </summary>
/// <param name="ballGo">Created game object of the ball</param>
/// <param name="id">Unique ID of the ball</param>
/// <param name="worldPos">Position in world space</param>
/// <param name="localPos">Position in local space</param>
/// <param name="localVel">Velocity in local space</param>
/// <param name="scale">Scale relative to ball mesh</param>
/// <param name="mass">Physics mass</param>
/// <param name="radius">Radius in local space</param>
/// <param name="kickerRef">If created within a kicker, this is the kicker entity</param>
void BallCreate(in float3 worldPos, in float3 localPos, in float3 localVel,
void BallCreate(GameObject ballGo, int id, in float3 worldPos, in float3 localPos, in float3 localVel,
in float scale, in float mass, in float radius, in Entity kickerRef);

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ public Shader GetShader()

private Shader GetShader(PbrMaterial vpxMaterial)
{
return vpxMaterial.VertexLerpWithUvEnabled
? Shader.Find("Visual Pinball/Built-In/LerpVertex")
: GetShader();
return GetShader();
}

public static Material GetDefaultMaterial(BlendMode blendMode)
Expand Down
Loading