- Replaced one skee-ball machine with two arcade machines.

- Added Black Horse And The Cherry Tree by KT Tunstall to the horse playlist.
- Added Buckin' My Horse by Sir Mix-A-Lot to the horse playlist.
This commit is contained in:
2026-02-11 02:58:41 -05:00
parent a7bcc5f056
commit 542e04afed
352 changed files with 45502 additions and 4988 deletions
+581
View File
@@ -0,0 +1,581 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3}
m_Name: Fruit
m_EditorClassIdentifier:
serializedUdonProgramAsset: {fileID: 11400000, guid: 6536ee11ddd092742ae839a53722b9cf,
type: 2}
udonAssembly:
assemblyError:
sourceCsScript: {fileID: 11500000, guid: f35b32852b537de4ba0292232fdca73a, type: 3}
scriptVersion: 2
compiledVersion: 2
behaviourSyncMode: 0
hasInteractEvent: 0
scriptID: -8248242574732920796
serializationData:
SerializedFormat: 2
SerializedBytes:
ReferencedUnityObjects: []
SerializedBytesString:
Prefab: {fileID: 0}
PrefabModificationsReferencedUnityObjects: []
PrefabModifications: []
SerializationNodes:
- Name: fieldDefinitions
Entry: 7
Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition,
UdonSharp.Editor]], mscorlib
- Name: comparer
Entry: 7
Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String,
mscorlib]], mscorlib
- Name:
Entry: 8
Data:
- Name:
Entry: 12
Data: 10
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: RigidbodyInstance
- Name: $v
Entry: 7
Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: RigidbodyInstance
- Name: <UserType>k__BackingField
Entry: 7
Data: 3|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.Rigidbody, UnityEngine.PhysicsModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 3
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 4|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: MeshRendererInstance
- Name: $v
Entry: 7
Data: 5|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: MeshRendererInstance
- Name: <UserType>k__BackingField
Entry: 7
Data: 6|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.MeshRenderer, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 6
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 7|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: FruitCollider
- Name: $v
Entry: 7
Data: 8|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: FruitCollider
- Name: <UserType>k__BackingField
Entry: 7
Data: 9|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.CapsuleCollider, UnityEngine.PhysicsModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 9
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 10|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _rank
- Name: $v
Entry: 7
Data: 11|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _rank
- Name: <UserType>k__BackingField
Entry: 7
Data: 12|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.Int16, mscorlib
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 12
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 13|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _melonGameLoopInstance
- Name: $v
Entry: 7
Data: 14|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _melonGameLoopInstance
- Name: <UserType>k__BackingField
Entry: 7
Data: 15|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: myro.arcade.MelonGameLoop, Assembly-CSharp
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 7
Data: 16|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: VRC.Udon.UdonBehaviour, VRC.Udon
- Name:
Entry: 8
Data:
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 17|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _currentColliderRadius
- Name: $v
Entry: 7
Data: 18|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _currentColliderRadius
- Name: <UserType>k__BackingField
Entry: 7
Data: 19|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.Single, mscorlib
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 19
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 20|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _gravityMultiplicator
- Name: $v
Entry: 7
Data: 21|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _gravityMultiplicator
- Name: <UserType>k__BackingField
Entry: 9
Data: 19
- Name: <SystemType>k__BackingField
Entry: 9
Data: 19
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 22|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _hadCollision
- Name: $v
Entry: 7
Data: 23|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _hadCollision
- Name: <UserType>k__BackingField
Entry: 7
Data: 24|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.Boolean, mscorlib
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 24
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 25|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _yAxisLimit
- Name: $v
Entry: 7
Data: 26|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _yAxisLimit
- Name: <UserType>k__BackingField
Entry: 9
Data: 19
- Name: <SystemType>k__BackingField
Entry: 9
Data: 19
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 27|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: _startTimeAboveLimit
- Name: $v
Entry: 7
Data: 28|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: _startTimeAboveLimit
- Name: <UserType>k__BackingField
Entry: 9
Data: 19
- Name: <SystemType>k__BackingField
Entry: 9
Data: 19
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: false
- Name: _fieldAttributes
Entry: 7
Data: 29|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5035f256cf13c144f8efaaf256a3a744
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
+171
View File
@@ -0,0 +1,171 @@
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
namespace myro.arcade
{
public class Fruit : UdonSharpBehaviour
{
public Rigidbody RigidbodyInstance;
public MeshRenderer MeshRendererInstance;
public CapsuleCollider FruitCollider;
private short _rank = 0;
private MelonGameLoop _melonGameLoopInstance;
private const float TARGET_COLLIDER_RADIUS = 0.5f;
private float _currentColliderRadius;
private float _gravityMultiplicator;
private bool _hadCollision;
#region Game Over Detection
private float _yAxisLimit; //If one fruit stays above that limit for more than a second, the game is lost
private float _startTimeAboveLimit;
private void CheckGameOver()
{
if (!_hadCollision)
{
return;
}
if (transform.localPosition.y - transform.localScale.x / 2.0f < _yAxisLimit
|| RigidbodyInstance.velocity.magnitude > 0.5f * transform.lossyScale.x)
{
//everything is alright
_startTimeAboveLimit = 0;
}
else if (_startTimeAboveLimit == 0
&& transform.localPosition.y - transform.localScale.x / 2.0f >= _yAxisLimit
&& RigidbodyInstance.velocity.magnitude <= 0.5f * transform.lossyScale.x)
{
//Dangerously close to a game over
_startTimeAboveLimit = Time.time;
}
else if (Time.time - _startTimeAboveLimit > 1.0f && _melonGameLoopInstance.GetGameState() != GameState.FINISH)
{
_melonGameLoopInstance.GameOver();
}
}
#endregion
public void Construct(Transform parent, MelonGameLoop melonGameLoopInstance, short rank, float gameScale, float yAxisLimit, bool isFused)
{
transform.parent = parent;
FruitCollider.enabled = false;
RigidbodyInstance.isKinematic = true;
_hadCollision = isFused;
_yAxisLimit = yAxisLimit;
_currentColliderRadius = TARGET_COLLIDER_RADIUS;
_gravityMultiplicator = gameScale;
_melonGameLoopInstance = melonGameLoopInstance;
RigidbodyInstance.drag = 0;
RigidbodyInstance.angularDrag = 1f;
SetRank(rank);
SetScaleAndRotation();
}
public short GetRank()
{
return _rank;
}
public void SetRank(short rank)
{
_rank = rank;
float fruitScale = 0.22f + rank * 0.147272f;
transform.localScale = Vector3.one * fruitScale;
RigidbodyInstance.mass = 1;
_melonGameLoopInstance.SetTextureOffset(MeshRendererInstance.material, rank);
}
private void SetScaleAndRotation()
{
FruitCollider.radius = _currentColliderRadius;
transform.localEulerAngles = new Vector3(0, 0, transform.localEulerAngles.z);
}
public void DropFruit()
{
FruitCollider.enabled = true;
RigidbodyInstance.isKinematic = false;
RigidbodyInstance.collisionDetectionMode = CollisionDetectionMode.Continuous;
_currentColliderRadius = TARGET_COLLIDER_RADIUS * 0.5f;
FruitCollider.contactOffset = 0.0001f; //Using the script "ColliderParameterSetter" didn't worked, so I am setting it here.
SetScaleAndRotation();
}
#region Unity Events
private void FixedUpdate()
{
if (!enabled)
return;
//Local velocity contraint
Vector3 localVelocity = transform.parent.InverseTransformDirection(RigidbodyInstance.velocity);
localVelocity.z = 0;
RigidbodyInstance.velocity = transform.parent.TransformDirection(localVelocity);
//Gravity on the local space
RigidbodyInstance.AddForce(transform.parent.up * -5f * _gravityMultiplicator * RigidbodyInstance.mass);
}
private void Update()
{
CheckGameOver();
_currentColliderRadius += (TARGET_COLLIDER_RADIUS - _currentColliderRadius) * Time.deltaTime * 3f;
//Local rotation contraint
SetScaleAndRotation();
//Local position contraint
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y, 0);
}
private void OnCollisionEnter(Collision collision)
{
if (gameObject.activeSelf && enabled)
{
if (_rank != 10)
{
Fruit anotherFruit = collision.gameObject.GetComponent<Fruit>();
if (anotherFruit && _rank == anotherFruit.GetRank() && collision.gameObject.activeSelf)
{
_melonGameLoopInstance.DestroyFruit(this);
_melonGameLoopInstance.DestroyFruit(anotherFruit);
_melonGameLoopInstance.IncrementComboAndPlayAudio();
gameObject.SetActive(false);
anotherFruit.gameObject.SetActive(false);
Fruit newFruit = _melonGameLoopInstance.InstantiateNewFruitAt((short)(_rank + 1), true);
newFruit.transform.localPosition = (anotherFruit.transform.localPosition + transform.localPosition) / 2.0f;
newFruit.DropFruit();
}
else if (!_hadCollision)
{
_melonGameLoopInstance.SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, nameof(_melonGameLoopInstance.PlayCollisionAudio));
}
}
}
if (!_hadCollision)
{
_melonGameLoopInstance.ReadyForNextFruit();
_hadCollision = true;
}
}
#endregion
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f35b32852b537de4ba0292232fdca73a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,113 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3}
m_Name: GameOverCollider
m_EditorClassIdentifier:
serializedUdonProgramAsset: {fileID: 11400000, guid: 894f1b3175e569e4fa472e9cba3e1fb0,
type: 2}
udonAssembly:
assemblyError:
sourceCsScript: {fileID: 11500000, guid: e636c2edb422a8146ae3fac62c9c549d, type: 3}
scriptVersion: 2
compiledVersion: 2
behaviourSyncMode: 1
hasInteractEvent: 0
scriptID: 839463665691077582
serializationData:
SerializedFormat: 2
SerializedBytes:
ReferencedUnityObjects: []
SerializedBytesString:
Prefab: {fileID: 0}
PrefabModificationsReferencedUnityObjects: []
PrefabModifications: []
SerializationNodes:
- Name: fieldDefinitions
Entry: 7
Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition,
UdonSharp.Editor]], mscorlib
- Name: comparer
Entry: 7
Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String,
mscorlib]], mscorlib
- Name:
Entry: 8
Data:
- Name:
Entry: 12
Data: 1
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: MelonGameLoopInstance
- Name: $v
Entry: 7
Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: MelonGameLoopInstance
- Name: <UserType>k__BackingField
Entry: 7
Data: 3|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: myro.arcade.MelonGameLoop, Assembly-CSharp
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 7
Data: 4|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: VRC.Udon.UdonBehaviour, VRC.Udon
- Name:
Entry: 8
Data:
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 5|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e1a6d304a23c0c44825481726fde4f2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,22 @@
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
namespace myro.arcade
{
[UdonBehaviourSyncMode(BehaviourSyncMode.None)]
public class GameOverCollider : UdonSharpBehaviour
{
public MelonGameLoop MelonGameLoopInstance;
private void OnCollisionEnter(Collision collision)
{
Fruit anotherFruit = collision.gameObject.GetComponent<Fruit>();
if (anotherFruit != null && MelonGameLoopInstance.GetGameState() != GameState.FINISH)
{
MelonGameLoopInstance.GameOver();
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e636c2edb422a8146ae3fac62c9c549d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 843b6e4b94109664b9136365648a19c9
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,438 @@
using TMPro;
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDK3.Data;
using VRC.SDKBase;
using VRC.Udon;
namespace myro.arcade
{
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class MelonGameLoop : UdonSharpBehaviour
{
public Transform LeftWall;
public Transform RightWall;
public Transform Root;
public Joystick JoystickInstance;
public Transform DropTransform;
public Transform DeathZone;
public GameObject FruitPrefab;
public GameObject GameOverMessage;
public MelonGameSettings MelonGameSettingsInstance;
public TextMeshProUGUI Score;
public MeshRenderer NextRankImage;
public AudioSource Music;
public AudioSource AudioPlayer;
public AudioSource ComboPlayer;
public AudioClip Drop;
public AudioClip Collision;
public AudioClip Combo;
private Fruit _currentFruit;
private DataList _instantiatedFruits;
private const float SYNCING_RATE = 0.2f;
private int _combo;
[UdonSynced]
private bool _joystickGrabbed;
[UdonSynced]
private GameState _gameState;
[UdonSynced]
private int _score;
[UdonSynced]
private short _nextRank;
[UdonSynced]
private Vector3[] _positionFruits;
[UdonSynced]
private Quaternion[] _rotationFruits;
[UdonSynced]
private short[] _rankFruits;
void Start()
{
_gameState = GameState.FINISH;
GameOver();
}
private short UpdateNextFruitViewAndReturnCurrentRank()
{
short newRank = _nextRank;
_nextRank = (short)Random.Range(0, 5);
UpdateNextRankImage();
return newRank;
}
private Vector3 GetCursorPosition()
{
float ratioX = JoystickInstance.GetPositionXRatio();
float radiusFruit = 0;
if (_currentFruit)
radiusFruit = _currentFruit.transform.localScale.x / 2.0f + 0.01f; //We add a little threshold at the end
Vector3 left = new Vector3(LeftWall.localPosition.x + radiusFruit, LeftWall.localPosition.y, LeftWall.localPosition.z);
Vector3 right = new Vector3(RightWall.localPosition.x - radiusFruit, RightWall.localPosition.y, RightWall.localPosition.z);
return Vector3.Lerp(left, right, ratioX);
}
public GameState GetGameState()
{
return _gameState;
}
public void NewFruit()
{
short rank = UpdateNextFruitViewAndReturnCurrentRank();
_currentFruit = InstantiateNewFruitAt(rank, false);
_currentFruit.transform.localPosition = GetCursorPosition();
_currentFruit.enabled = false;
}
public void SetTextureOffset(Material mat, int rank)
{
mat.SetTextureOffset("_MainTex", new Vector2((rank % 4) / 4.0f, (rank / 4) / 4.0f));
}
private void StartGame()
{
if (_instantiatedFruits != null)
{
for (int i = 0; i < _instantiatedFruits.Count; i++)
{
Fruit fruit = (Fruit)_instantiatedFruits[i].Reference;
if (fruit)
Destroy(fruit.gameObject);
}
}
_instantiatedFruits = new DataList();
_score = 0;
_gameState = GameState.PLAY;
NewFruit();
SyncingLoop();
UpdateUIState();
Music.Play();
}
public void AddToScore(int points)
{
_score += points;
UpdateScore();
}
#region Events and syncing
/// <summary>
/// This looping method should only be called by the owner, it syncs the data
/// </summary>
public void SyncingLoop()
{
if (_gameState == GameState.FINISH || _instantiatedFruits == null || !Networking.IsOwner(gameObject))
return;
int length = _instantiatedFruits.Count;
_positionFruits = new Vector3[length];
_rotationFruits = new Quaternion[length];
_rankFruits = new short[length];
for (int i = 0; i < length; i++)
{
Fruit fruit = (Fruit)_instantiatedFruits[i].Reference;
if (!fruit)
return;
_positionFruits[i] = fruit.transform.localPosition;
_rotationFruits[i] = fruit.transform.localRotation;
_rankFruits[i] = fruit.GetRank();
}
RequestSerialization();
SendCustomEventDelayedSeconds(nameof(SyncingLoop), SYNCING_RATE);
}
/// <summary>
/// This event is called from the Joystick script
/// </summary>
public void PlayerPickedUpJoystick()
{
if (!Networking.IsOwner(gameObject))
{
Networking.SetOwner(Networking.LocalPlayer, gameObject);
StartGame();
}
_joystickGrabbed = true;
RequestSerialization();
/*WaitMessage.SetActive(!Networking.IsOwner(gameObject) && _gameState == GameState.PLAY);
if (_gameState == GameState.FINISH)
{
Networking.SetOwner(Networking.LocalPlayer, gameObject);
}*/
}
/// <summary>
/// This event is called from the Joystick script
/// </summary>
public void PlayerDroppedJoystick()
{
_joystickGrabbed = false;
RequestSerialization();
}
bool _isPlayerInArea;
public void OnPlayerEnteredArea()
{
_isPlayerInArea = true;
}
public void OnPlayerExitedArea()
{
_isPlayerInArea = false;
}
public override void OnOwnershipTransferred(VRCPlayerApi player)
{
if (!player.isLocal)
{
_currentFruit = null;
}
}
public void OnPress()
{
if (!Networking.IsOwner(gameObject))
return;
if (_gameState == GameState.PLAY)
{
if (_currentFruit != null)
{
_currentFruit.enabled = true;
_currentFruit.DropFruit();
_currentFruit = null;
_combo = 0;
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, nameof(PlayDropAudio));
}
}
else
{
StartGame();
}
}
public void OnResetPressed()
{
if (_joystickGrabbed)
return;
if (!Networking.IsOwner(gameObject))
Networking.SetOwner(Networking.LocalPlayer, gameObject);
StartGame();
}
// Here, OnDeserialization should only be called for the remote player
public override void OnDeserialization()
{
if (!_isPlayerInArea)
return;
if (_gameState == GameState.PLAY && !Music.isPlaying)
Music.Play();
else if (_gameState == GameState.FINISH && Music.isPlaying)
Music.Stop();
UpdateUI();
if (_instantiatedFruits == null)
{
_instantiatedFruits = new DataList();
}
int numberOfSyncedFruits = _positionFruits.Length;
//first for-loop to check if all references are valid, this is to prevent possible errors
for (int i = _instantiatedFruits.Count - 1; i >= 0; i--)
{
Fruit fruit = (Fruit)_instantiatedFruits[i].Reference;
if (!Utilities.IsValid(fruit))
{
_instantiatedFruits.RemoveAt(i);
}
}
if (_instantiatedFruits.Count < numberOfSyncedFruits)
{
//Here we need to instantiate more fruits
for (int i = 0; i < numberOfSyncedFruits - _instantiatedFruits.Count; i++)
{
InstantiateNewFruitAt(0, false); //the settings will be set later
}
}
else if (_instantiatedFruits.Count > numberOfSyncedFruits)
{
//Here we need to destroy a few fruits
for (int i = 0; i < _instantiatedFruits.Count - numberOfSyncedFruits; i++)
{
Fruit fruit = (Fruit)_instantiatedFruits[0].Reference;
Destroy(fruit.gameObject);
_instantiatedFruits.RemoveAt(0);
}
}
for (int i = 0; i < numberOfSyncedFruits; i++)
{
if (_instantiatedFruits[i].Error == DataError.None)
{
//Now we update each fruit
Fruit fruit = (Fruit)_instantiatedFruits[i].Reference;
fruit.transform.localPosition = _positionFruits[i];
fruit.transform.localRotation = _rotationFruits[i];
fruit.SetRank(_rankFruits[i]);
fruit.enabled = false; //the scripts does not need to be enabled for the remote player
}
}
}
#endregion
#region UI
private void UpdateNextRankImage()
{
SetTextureOffset(NextRankImage.material, _nextRank);
float scale = (_nextRank + 1) + 1.0f;
NextRankImage.transform.localScale = new Vector3(scale, scale, scale);
}
private void UpdateScore()
{
Score.text = _score.ToString();
}
private void UpdateUIState()
{
GameOverMessage.SetActive(_gameState == GameState.FINISH);
}
private void UpdateUI()
{
UpdateScore();
UpdateUIState();
UpdateNextRankImage();
}
#endregion
public void GameOver()
{
Music.Stop();
if (_currentFruit != null)
{
Destroy(_currentFruit.gameObject);
_currentFruit = null;
}
_gameState = GameState.FINISH;
UpdateUI();
//pausing all physics
if (_instantiatedFruits != null)
{
for (int i = 0; i < _instantiatedFruits.Count; i++)
{
Fruit fruit = (Fruit)_instantiatedFruits[i].Reference;
if (fruit)
{
fruit.RigidbodyInstance.collisionDetectionMode = CollisionDetectionMode.Discrete; //to avoid warnings...
fruit.RigidbodyInstance.isKinematic = true;
fruit.enabled = false;
}
}
}
if (_score > 32 && MelonGameSettingsInstance.SharedScoreboardPrefab)
{
MelonGameSettingsInstance.SharedScoreboardPrefab.Insert(Networking.LocalPlayer, _score);
}
RequestSerialization();
}
public Fruit InstantiateNewFruitAt(short rank, bool isFused)
{
Fruit newFruit = Instantiate(FruitPrefab).GetComponent<Fruit>();
newFruit.Construct(Root, this, rank, transform.lossyScale.x, DeathZone.localPosition.y, isFused);
_instantiatedFruits.Add(newFruit);
AddToScore(1 << rank);
return newFruit;
}
internal void DestroyFruit(Fruit anotherFruit)
{
_instantiatedFruits.Remove(anotherFruit);
Destroy(anotherFruit.gameObject);
}
private void Update()
{
if (_currentFruit != null)
{
_currentFruit.transform.localPosition = GetCursorPosition();
}
}
public void ReadyForNextFruit()
{
NewFruit();
}
#region Audio
public void IncrementComboAndPlayAudio()
{
_combo++;
ComboPlayer.pitch = 1 + _combo / 6.0f;
SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, nameof(PlayComboAudio));
}
public void PlayComboAudio()
{
if (!_isPlayerInArea)
return;
ComboPlayer.PlayOneShot(Combo);
}
public void PlayCollisionAudio()
{
if (!_isPlayerInArea)
return;
AudioPlayer.PlayOneShot(Collision);
}
public void PlayDropAudio()
{
if (!_isPlayerInArea)
return;
AudioPlayer.PlayOneShot(Drop);
}
#endregion
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 51ec9f3adf6c4ff4c8098c88f688acca
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,275 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c333ccfdd0cbdbc4ca30cef2dd6e6b9b, type: 3}
m_Name: MelonGameSettings
m_EditorClassIdentifier:
serializedUdonProgramAsset: {fileID: 11400000, guid: a347607949075d54f8d764e9db4e4150,
type: 2}
udonAssembly:
assemblyError:
sourceCsScript: {fileID: 11500000, guid: 4e3099317cf3b0b44baf30239a879233, type: 3}
scriptVersion: 2
compiledVersion: 2
behaviourSyncMode: 1
hasInteractEvent: 0
scriptID: -4416642098132397736
serializationData:
SerializedFormat: 2
SerializedBytes:
ReferencedUnityObjects: []
SerializedBytesString:
Prefab: {fileID: 0}
PrefabModificationsReferencedUnityObjects: []
PrefabModifications: []
SerializationNodes:
- Name: fieldDefinitions
Entry: 7
Data: 0|System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[UdonSharp.Compiler.FieldDefinition,
UdonSharp.Editor]], mscorlib
- Name: comparer
Entry: 7
Data: 1|System.Collections.Generic.GenericEqualityComparer`1[[System.String,
mscorlib]], mscorlib
- Name:
Entry: 8
Data:
- Name:
Entry: 12
Data: 4
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: RenderTextureToUse
- Name: $v
Entry: 7
Data: 2|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: RenderTextureToUse
- Name: <UserType>k__BackingField
Entry: 7
Data: 3|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.RenderTexture, UnityEngine.CoreModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 3
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 4|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: ScreenShaderEmissionPropertyName
- Name: $v
Entry: 7
Data: 5|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: ScreenShaderEmissionPropertyName
- Name: <UserType>k__BackingField
Entry: 7
Data: 6|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: System.String, mscorlib
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 6
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 7|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: SharedScoreboardPrefab
- Name: $v
Entry: 7
Data: 8|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: SharedScoreboardPrefab
- Name: <UserType>k__BackingField
Entry: 7
Data: 9|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: myro.arcade.SharedScoreboard, Assembly-CSharp
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 7
Data: 10|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: VRC.Udon.UdonBehaviour, VRC.Udon
- Name:
Entry: 8
Data:
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 11|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 7
Data:
- Name: $k
Entry: 1
Data: Music
- Name: $v
Entry: 7
Data: 12|UdonSharp.Compiler.FieldDefinition, UdonSharp.Editor
- Name: <Name>k__BackingField
Entry: 1
Data: Music
- Name: <UserType>k__BackingField
Entry: 7
Data: 13|System.RuntimeType, mscorlib
- Name:
Entry: 1
Data: UnityEngine.AudioClip, UnityEngine.AudioModule
- Name:
Entry: 8
Data:
- Name: <SystemType>k__BackingField
Entry: 9
Data: 13
- Name: <SyncMode>k__BackingField
Entry: 7
Data: System.Nullable`1[[UdonSharp.UdonSyncMode, UdonSharp.Runtime]], mscorlib
- Name:
Entry: 6
Data:
- Name:
Entry: 8
Data:
- Name: <IsSerialized>k__BackingField
Entry: 5
Data: true
- Name: _fieldAttributes
Entry: 7
Data: 14|System.Collections.Generic.List`1[[System.Attribute, mscorlib]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 8
Data:
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1189000fb8e501f4f87596977c43ee0d
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,13 @@
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
namespace myro.arcade
{
public class MelonGameSettings : GameSettings
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4e3099317cf3b0b44baf30239a879233
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: