我有两个字符'Alisha'和'John',他们之间有30的意见。但是我真正想要实现的是Alisha对john 20的看法,John对Alisha 20的看法。创建一个3D阵列来解决该问题。
我创建了两个带有意见数组的脚本对象“字符”和“ OpinionsTable”。我基本上实现了我想要的。例如,我的代码非常适合用于Characters。我还创建了一个编辑器脚本,该脚本创建了意见矩阵,但我想将其增强为3D矩阵。
Character.cs
using UnityEngine;
[CreateAssetMenu()]
public class Character : ScriptableObject
{
public string Name;
}
OpinionsTable.cs
using UnityEngine;
[CreateAssetMenu()]
public class OpinionsTable : ScriptableObject
{
[SerializeField]
private Character[] characters;
[SerializeField]
private int[] opinions;
public int this[int i, int j] // Where i and j are indices of characters in the array above
{
get { return opinions[i * characters.Length + j]; }
set { opinions[i * characters.Length + j] = value; }
}
}
OpinionsTableEditor.cs
using UnityEngine;
using UnityEditor;
[CustomEditor( typeof( OpinionsTable ) )]
public class OpinionsTableEditor : Editor
{
const float opinionsLabelWidth = 50;
const float opinionCellSize = 25;
SerializedProperty characters;
SerializedProperty opinions;
int opinionsTableWidth = 0;
Rect opinionsTableRect;
void OnEnable()
{
// Retrieve the serialized properties
characters = serializedObject.FindProperty( "characters" );
opinions = serializedObject.FindProperty( "opinions" );
}
public override void OnInspectorGUI()
{
serializedObject.Update();
// Check if the number of characters has been changed
// If so, resize the opinions
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField( characters, true );
if( EditorGUI.EndChangeCheck() )
{
opinions.arraySize = characters.arraySize * characters.arraySize;
}
// Draw opinions if there is more than one character
if ( opinions.arraySize > 1 )
DrawOpinions( opinions, characters );
else
EditorGUILayout.LabelField( "Not enough characters to draw opinions matrix" );
serializedObject.ApplyModifiedProperties();
}
private void DrawOpinions( SerializedProperty opinions, SerializedProperty characters )
{
int charactersCount = characters.arraySize;
if ( Event.current.type == EventType.Layout )
opinionsTableWidth = Mathf.FloorToInt( EditorGUIUtility.currentViewWidth );
// Get the rect of the whole matric, labels included
Rect rect = GUILayoutUtility.GetRect(opinionsTableWidth, opinionsTableWidth, EditorStyles.inspectorDefaultMargins);
if ( opinionsTableWidth > 0 && Event.current.type == EventType.Repaint )
opinionsTableRect = rect;
// Draw matrix and labels only if the rect has been computed
if( opinionsTableRect.width > 0 )
{
// Compute size of opinion cell
float cellWidth = Mathf.Min( (opinionsTableRect.width - opinionsLabelWidth) / charactersCount, opinionCellSize );
Rect opinionCell = new Rect( opinionsTableRect.x + opinionsLabelWidth, opinionsTableRect.y + opinionsLabelWidth, cellWidth, cellWidth );
Matrix4x4 guiMatrix = GUI.matrix;
// Draw vertical labels
for ( int i = 1 ; i <= charactersCount ; ++i )
{
Rect verticalLabelRect = new Rect( opinionsTableRect.x + opinionsLabelWidth + i * opinionCell.width, opinionsTableRect.y, opinionsLabelWidth, opinionsLabelWidth );
Character character = characters.GetArrayElementAtIndex( i - 1 ).objectReferenceValue as Character;
EditorGUIUtility.RotateAroundPivot( 90f, new Vector2( verticalLabelRect.x, verticalLabelRect.y ) );
EditorGUI.LabelField( verticalLabelRect, character == null ? "???" : character.Name );
GUI.matrix = guiMatrix;
}
// Draw matrix
for ( int i = 0 ; i < charactersCount ; ++i )
{
// Draw horizontal labels
SerializedProperty characterProperty = characters.GetArrayElementAtIndex( i );
Character character = characterProperty == null ? null : characters.GetArrayElementAtIndex( i ).objectReferenceValue as Character;
EditorGUI.LabelField( new Rect( opinionsTableRect.x, opinionCell.y, opinionsLabelWidth, opinionCell.height ), character == null ? "???" : character.Name ) ;
for ( int j = 0 ; j < charactersCount ; ++j )
{
opinionCell.x = opinionsTableRect.x + opinionsLabelWidth + j * cellWidth;
if ( j > i )
{
SerializedProperty opinion = opinions.GetArrayElementAtIndex( i * charactersCount + j );
opinion.intValue = EditorGUI.IntField( opinionCell, opinion.intValue );
}
else // Put grey box because the matrix is symmetrical
{
EditorGUI.DrawRect( opinionCell, Color.grey );
}
}
opinionCell.y += cellWidth;
}
}
}
}
我得到了正确的矩阵,还可以设置两个字符的值。
但是我要实现的两个角色之间应该有两种意见,例如a的b意见和b的a意见。如果您可以提供一种将一种意见的价值存储到另一种int的方法,那也很好。
答案 0 :(得分:1)
正如我已经回答here一样,您不需要3D阵列,只需要允许编辑整个矩阵即可:
可以,但是您不需要3D阵列。您只需要允许编辑矩阵的左下角:
for ( int j = 0 ; j < charactersCount ; ++j )
{
opinionCell.x = opinionsTableRect.x + opinionsLabelWidth + j * cellWidth;
if ( j > i )
{
SerializedProperty opinion = opinions.GetArrayElementAtIndex( i * charactersCount + j );
opinion.intValue = EditorGUI.IntField( opinionCell, opinion.intValue );
}
else // Put grey box because the matrix is symmetrical
{
EditorGUI.DrawRect( opinionCell, Color.grey );
}
}
必须替换为
for ( int j = 0 ; j < charactersCount ; ++j )
{
opinionCell.x = opinionsTableRect.x + opinionsLabelWidth + j * cellWidth;
SerializedProperty opinion = opinions.GetArrayElementAtIndex( i * charactersCount + j );
opinion.intValue = EditorGUI.IntField( opinionCell, opinion.intValue );
}