Skip to content

Instantly share code, notes, and snippets.

@20chan
Last active August 28, 2019 08:27
Show Gist options
  • Save 20chan/ae0b3eaafdfbea02f427f7a04c9d1014 to your computer and use it in GitHub Desktop.
Save 20chan/ae0b3eaafdfbea02f427f7a04c9d1014 to your computer and use it in GitHub Desktop.
Random rated object picker unity extension
using System;
using Object = UnityEngine.Object;
using Random = UnityEngine.Random;
[Serializable]
public class RandomRateObject<T> : RandomRateObjectBase where T : Object {
// rates.Length + 1 = objects.Length
public float[] rates = new float[0];
public T[] objects = new T[1];
public T PickOne() {
int i = 0;
var cur = 0f;
for (; i < rates.Length; i++) {
cur += rates[i];
if (Random.Range(0, 1f) < cur) {
return objects[i];
}
}
return objects[i];
}
}
public class RandomRateObjectBase {}
using UnityEditor;
using UnityEngine;
[CustomPropertyDrawer(typeof(RandomRateObjectBase), true)]
public class RandomRateGameObjectDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
var rates = property.FindPropertyRelative("rates");
var objects = property.FindPropertyRelative("objects");
var type = property.serializedObject.targetObject
.GetType()
.GetField(property.propertyPath)
.FieldType
.BaseType
.GetGenericArguments()[0];
var fullRect = position;
var height = position.height / (rates.arraySize + 3);
EditorGUI.BeginProperty(fullRect, label, property);
var labelRect = new Rect(fullRect.x, fullRect.y, fullRect.width, height);
EditorGUI.LabelField(labelRect, label);
var total = 0f;
int i = 0;
var objWidth = 150;
for (; i < rates.arraySize; i++) {
var objRect = new Rect(fullRect.x, fullRect.y + height * (i + 1), objWidth, height);
var rect = new Rect(fullRect.x + objWidth, fullRect.y + height * (i + 1), fullRect.width - objWidth, height);
var rate = rates.GetArrayElementAtIndex(i);
var val = rate.floatValue;
var obj = objects.GetArrayElementAtIndex(i);
var objNewValue = EditorGUI.ObjectField(objRect, obj.objectReferenceValue, type, true);
obj.objectReferenceValue = objNewValue;
obj.serializedObject.ApplyModifiedProperties();
val = EditorGUI.Slider(rect, val, 0, 1);
val = Mathf.Clamp(val, val, 1f - total);
rate.floatValue = val;
rate.serializedObject.ApplyModifiedProperties();
total += val;
}
i++;
var leftObjRect = new Rect(fullRect.x, fullRect.y + height * i, objWidth, height);
var leftRect = new Rect(fullRect.x + objWidth, fullRect.y + height * i, fullRect.width - objWidth, height);
var leftObj = objects.GetArrayElementAtIndex(objects.arraySize - 1);
var leftObjNewVal = EditorGUI.ObjectField(leftObjRect, leftObj.objectReferenceValue, type, true);
leftObj.objectReferenceValue = leftObjNewVal;
leftObj.serializedObject.ApplyModifiedProperties();
EditorGUI.Slider(leftRect, 1f - total, 0, 1);
i++;
var btnWidth = fullRect.width / 2;
var leftBtnRect = new Rect(fullRect.x, fullRect.y + height * i, btnWidth, height);
var rightBtnRect = new Rect(fullRect.x + btnWidth, fullRect.y + height * i, btnWidth, height);
if (GUI.Button(leftBtnRect, "+1")) {
rates.InsertArrayElementAtIndex(rates.arraySize);
objects.InsertArrayElementAtIndex(objects.arraySize);
}
if (GUI.Button(rightBtnRect, "-1")) {
if (rates.arraySize <= 0) {
return;
}
rates.DeleteArrayElementAtIndex(rates.arraySize - 1);
objects.DeleteArrayElementAtIndex(objects.arraySize - 1);
}
EditorGUI.EndProperty();
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
return 16 * (property.FindPropertyRelative("rates").arraySize + 4);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment