WorldItem.cs is for objects that can be interacted with in the world. There’s not much to this script yet but it’s intended to control the function of elevators, keypads, power supply, circuit breaker, doors and other objects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

// Eric's item's in the world script, interacts directy with ItemsInventory script?? Physics Raycasting will be handled in interactions script
public class WorldItem : MonoBehaviour
{

    public enum UsableTypes { Door = 1, Elevator, Fusebox, Keypad, TV, Computer, CassettePlayer, PowerSupply };

    [Header("Pickable item variables")]
    public bool pickable = false;
    public GameObject inventoryCounterpart; // actual card, not from project window, as none of the cards get instantiated or destroyed just pulled and put from the deck


    [Header("Usable item variables")]
    public bool usable = false;
    public UsableTypes usableType;
    public List<GameObject> requiredItems;


    // items setup variables
    private HingeJoint myHingeJoint;
    private JointSpring mySpring;

    // temp door testing remember to remove from custom inspector
    public bool locked = true;

    // instead of onmouseover use a while getting hit by raycast so the only time this script is running is while getting hit otherwise it might be listening all the time for a hit.

    private void Awake()
    {
        // set up all items according to type, add all spawnpoints on usable items to list
        myHingeJoint = this.GetComponent<HingeJoint>();

        if (GetComponent<HingeJoint>() != null)
        {
            //Debug.Log("my hinge joint isn't null");
            //mySpring = myHingeJoint.spring;
            mySpring = GetComponent<HingeJoint>().spring;


        } // must be a door?   use enum instead of checking if it has a hinge

        Debug.Log("The first required item is" + requiredItems[0]);
    }


    private void Start()
    {
        //Debug.Log(name + " has been created" + " and pickable = " + pickable);
    }

    public void ContextMenu()
    {
        // receive right click activation from world interactions script, not sure why at the moment but kinda makes sense as inventory and interactions mostly track input
        // with less tracked in items scripts

        // rightclick context menu? Bools for the script will allow every object with this script to have different
        // context menu options which will allow each option to run it's equivalent script with itself(this/raycastresults/whatever) as the input
    }

    // overload use for different world item types?
    public void Use()
    {
        //Debug.Log("world item has been used");
        if (!locked)
        {
            if (myHingeJoint != null)
            {

                mySpring.targetPosition = 80f;
                myHingeJoint.spring = mySpring; // argh, all night to find out that I have to take it out save a variable then save the variable back into it

                //Debug.Log("setting target position on jointspring variable to " + mySpring.targetPosition);
                //Debug.Log("target position for hingejoint " + myHingeJoint.spring.targetPosition);
            }
        }

        // send item type from world interaction to set conditions and determine how use should work

        // if doesn't have required items post message to screen "door is locked" or appropriate message



        // if door unlocked and mouse drag detected then use transform.lookat on an empty gameobject and upvector with:
        // Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane))
        // and match target position under hinge joint, spring for door with empty gameobject



        // if mouse not dragged then default open door, set target position to open, 80 degrees? Animation and OnOff anim boolean is not needed using this technique
        // Be aware that taget position number doesn't guarantee y rotation on door transform, alter spring, drag, and rigid body mass until you get the effect you want
    }

    // temporary door lock method, goes with the temp lock variables
    public void UnlockDoor(GameObject redKey)
    {
        if (redKey == requiredItems[0]) { locked = false; }
    }
}










#region custom inspector
// I wonder if this will error on game build? Does a class that inherits editor need to be separated from classes that get built into the game?
//[CanEditMultipleObjects]
[CustomEditor(typeof(WorldItem))]
public class WorldItemEditor : Editor
{
    SerializedProperty usableType; // WorldItem.usableType?? if this script doesn't modify the list and enum properly then there's probably a targeting issue
    SerializedProperty requiredItems;


    private void OnEnable()
    {
        requiredItems = serializedObject.FindProperty("requiredItems");
    }


    override public void OnInspectorGUI()
    {

        WorldItem worldItem = target as WorldItem;

        // temporary door variables
        worldItem.locked = EditorGUILayout.Toggle("doorLocked", worldItem.locked);


        //EditorGUILayout.LabelField("Pickable ", EditorStyles.boldLabel);
        worldItem.pickable = EditorGUILayout.Toggle("Pickable", worldItem.pickable);
        using (new EditorGUI.DisabledScope(!worldItem.pickable))
        {
            worldItem.inventoryCounterpart = (GameObject)EditorGUILayout.ObjectField("Inventory Counterpart", worldItem.inventoryCounterpart, typeof(GameObject), true);
        }


        EditorGUILayout.LabelField(" ", EditorStyles.boldLabel); // just a line spacer
        worldItem.usable = EditorGUILayout.Toggle("Usable", worldItem.usable);
        using (new EditorGUI.DisabledScope(!worldItem.usable))
        {
            // https://answers.unity.com/questions/26207/how-can-i-recreate-the-array-inspector-element-for.html

            serializedObject.Update();

            //EditorGUIUtility.LookLikeInspector(); // deprecated, url above has a reply with an "alternative"
            usableType = serializedObject.FindProperty("usableType"); // WorldItem.usableType?? read SerializedProperty usableType; above
            requiredItems = serializedObject.FindProperty("requiredItems");

            EditorGUI.BeginChangeCheck();

            EditorGUILayout.PropertyField(usableType, true);
            EditorGUILayout.PropertyField(requiredItems, true);

            if (EditorGUI.EndChangeCheck())
                serializedObject.ApplyModifiedProperties();

            //EditorGUIUtility.LookLikeControls(); // deprectaed


            //EditorGUILayout.PropertyField(requiredItems, new GUIContent("requiredItems")); //worldItem.requiredItems =
        }
    }
}
#endregion