Skip to content

Instantly share code, notes, and snippets.

@gatosyocora
Last active July 14, 2020 22:10
Show Gist options
  • Save gatosyocora/3f104b9b6a0843dc9643b6a452b0b22c to your computer and use it in GitHub Desktop.
Save gatosyocora/3f104b9b6a0843dc9643b6a452b0b22c to your computer and use it in GitHub Desktop.
VRChatでインスタンス作成時にActiveにするオブジェクト(本スクリプトでは服装)をランダムで決定するUdonSharpスクリプト(確率と時間指定に対応)
using System;
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;
using VRC.Udon.Common.Interfaces;
public class NPCDressChanger : UdonSharpBehaviour
{
[SerializeField]
private int dressId = -1;
[SerializeField]
private GameObject defaultDress;
[SerializeField]
private GameObject[] normalDresses;
[SerializeField]
private GameObject[] specialDresses;
[SerializeField]
private Vector2[] specialDressTime; // 8:00~14:00の場合, 800 1400のように値を設定する
[SerializeField]
private int defaultDressRate = 1;
[SerializeField]
private int[] normalDressRates;
[SerializeField]
private int[] specialDressRates;
private bool defaultOnly = false;
[SerializeField]
private Toggle defaultOnlyToggle;
private GameObject[] dresses;
private void Start()
{
dresses = GetDresses();
}
public override void OnPlayerJoined(VRCPlayerApi player)
{
if (Networking.IsMaster)
{
// インスタンス生成後にランダムに選ぶ
if (dressId == -1)
{
// 現在の時間で出現可能なスペシャル衣装のindexを取得
var nowTime = DateTime.Now.Hour * 100 + DateTime.Now.Minute;
var availableSpecialDressIndices = new int[specialDresses.Length];
var addSpecialIndex = 0;
for (int i = 0; i < specialDressTime.Length; i++)
{
if (specialDressTime[i].x <= specialDressTime[i].y)
{
if (nowTime >= specialDressTime[i].x && nowTime <= specialDressTime[i].y)
{
availableSpecialDressIndices[addSpecialIndex++] = i;
}
}
else
{
if (nowTime >= specialDressTime[i].x || nowTime <= specialDressTime[i].y)
{
availableSpecialDressIndices[addSpecialIndex++] = i;
}
}
}
// 確率機を作成
// とりあえず現状は等倍率で出る
var maxSize = defaultDressRate;
foreach (var rate in normalDressRates)
{
maxSize += rate;
}
foreach (var rate in specialDressRates)
{
maxSize += rate;
}
var tmpBox = new int[maxSize];
var addIndex = 0;
// デフォルト衣装
for (int i = 0; i < defaultDressRate; i++)
{
tmpBox[addIndex++] = 0;
}
// 基本衣装
for (int i = 0; i < normalDresses.Length; i++)
{
for (int j = 0; j < normalDressRates[i]; j++)
{
tmpBox[addIndex++] = i + 1;
}
}
// 特殊衣装
// addSpecialIndex == 利用可能な衣装の個数
for (int i = 0; i < addSpecialIndex; i++)
{
var specialDressIndex = availableSpecialDressIndices[i];
for (int j = 0; j < specialDressRates[specialDressIndex]; j++)
{
tmpBox[addIndex++] = normalDresses.Length + 1 + specialDressIndex;
}
}
var gachaBox = new int[addIndex];
for (int i = 0; i < addIndex; i++)
{
gachaBox[i] = tmpBox[i];
}
dressId = gachaBox[UnityEngine.Random.Range(0, gachaBox.Length)];
}
ChangeDressSync(dressId);
if (defaultOnly)
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(SetDefaultOnlyToTrue));
}
else
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(SetDefaultOnlyToFalse));
}
}
}
public void ChangeDressSync(int dressId)
{
switch (dressId)
{
case 0:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo0));
break;
case 1:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo1));
break;
case 2:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo2));
break;
case 3:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo3));
break;
case 4:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo4));
break;
case 5:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo5));
break;
case 6:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo6));
break;
case 7:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo7));
break;
case 8:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo8));
break;
case 9:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo9));
break;
case 10:
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo10));
break;
default:
break;
}
}
private GameObject[] GetDresses()
{
var dresses = new GameObject[1 + normalDresses.Length + specialDresses.Length];
var addIndex = 0;
dresses[addIndex++] = defaultDress;
foreach (var dress in normalDresses)
{
dresses[addIndex++] = dress;
}
foreach (var dress in specialDresses)
{
dresses[addIndex++] = dress;
}
return dresses;
}
private void ChangeDress(int dressId)
{
for (int i = 0; i < dresses.Length; i++)
{
dresses[i].SetActive(false);
}
dresses[dressId].SetActive(true);
}
public void ChangeDressTo0Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo0));
}
public void ChangeDressTo1Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo1));
}
public void ChangeDressTo2Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo2));
}
public void ChangeDressTo3Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo3));
}
public void ChangeDressTo4Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo4));
}
public void ChangeDressTo5Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo5));
}
public void ChangeDressTo6Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo6));
}
public void ChangeDressTo7Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo7));
}
public void ChangeDressTo8Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo8));
}
public void ChangeDressTo9Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo9));
}
public void ChangeDressTo10Sync()
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ChangeDressTo10));
}
public void ChangeDressTo0()
{
dressId = 0;
ChangeDress(0);
}
public void ChangeDressTo1()
{
dressId = 1;
ChangeDress(1);
}
public void ChangeDressTo2()
{
dressId = 2;
ChangeDress(2);
}
public void ChangeDressTo3()
{
dressId = 3;
ChangeDress(3);
}
public void ChangeDressTo4()
{
dressId = 4;
ChangeDress(4);
}
public void ChangeDressTo5()
{
dressId = 5;
ChangeDress(5);
}
public void ChangeDressTo6()
{
dressId = 6;
ChangeDress(6);
}
public void ChangeDressTo7()
{
dressId = 7;
ChangeDress(7);
}
public void ChangeDressTo8()
{
dressId = 8;
ChangeDress(8);
}
public void ChangeDressTo9()
{
dressId = 9;
ChangeDress(9);
}
public void ChangeDressTo10()
{
dressId = 10;
ChangeDress(10);
}
public void ChangeDefaultOnlyStateSync()
{
if (Networking.IsMaster)
{
defaultOnly = !defaultOnly;
if (defaultOnly)
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(SetDefaultOnlyToTrue));
}
else
{
SendCustomNetworkEvent(NetworkEventTarget.All, nameof(SetDefaultOnlyToFalse));
}
}
else
{
// Master以外は押しても変更されない
defaultOnlyToggle.isOn = defaultOnly;
}
}
public void SetDefaultOnlyToTrue()
{
defaultOnly = true;
defaultOnlyToggle.isOn = defaultOnly;
ChangeDress(0);
}
public void SetDefaultOnlyToFalse()
{
defaultOnly = false;
defaultOnlyToggle.isOn = defaultOnly;
ChangeDress(dressId);
}
public override void Interact()
{
dressId = -1;
OnPlayerJoined(Networking.LocalPlayer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment