public static EventTriggerListener Get(GameObject go)
 {
     //EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
     //if (listener == null)
     //    listener = go.AddComponent<EventTriggerListener>();
     //EventTriggerListener listener = go.GetOrAddComponent<EventTriggerListener>();
     return go.GetOrAddComponent<EventTriggerListener>();
 }
		/// Convinience method for creating a GameObject with a set of colored cubes components attached.
		/**
		 * Adding a volume to a scene requires creating a GameObject and then attching the required Cubiquity components such a renderer and a
		 * collider. This method simply automates the process and also attaches the provided volume data.
		 * 
		 * \param data The volume data which should be attached to the construced volume.
		 * \param addRenderer Specifies whether a renderer component should be added so that the volume is displayed.
		 * \param addCollider Specifies whether a collider component should be added so that the volume can participate in collisions.
		 */
		public static GameObject CreateGameObject(ColoredCubesVolumeData data, bool addRenderer, bool addCollider)
		{
			// Create our main game object representing the volume.
			GameObject coloredCubesVolumeGameObject = new GameObject("Colored Cubes Volume");
			
			//Add the required volume component.
			ColoredCubesVolume coloredCubesVolume = coloredCubesVolumeGameObject.GetOrAddComponent<ColoredCubesVolume>();
			
			// Set the provided data.
			coloredCubesVolume.data = data;
			
			// Add the renderer and collider if desired.
			if(addRenderer) { coloredCubesVolumeGameObject.AddComponent<ColoredCubesVolumeRenderer>(); }
			if(addCollider) { coloredCubesVolumeGameObject.AddComponent<ColoredCubesVolumeCollider>(); }
			
			// Return the created object
			return coloredCubesVolumeGameObject;
		}
        /// Give an existing GameObject an icBinkMaterial with a given local Bink file.
        public icBinkMaterial CreateBinkMaterial(string filePath, GameObject go)
        {
            if (ToolbeltManager.FirstInstance.useBink)
            {
            icBinkMaterial mat = go.GetComponent<icBinkMaterial>();

            if (mat == null)
                mat = go.AddComponent<icBinkMaterial>();

            BinkPlugin bp = go.GetOrAddComponent<BinkPlugin>();
            mat.LoadMovie(filePath, bp);

            return mat;
            }
            else {
            Debug.LogWarning("Tried to CreateBinkMaterial() when ToolbeltManager::useBink is false. Returning null. \"" + filePath + "\"");
            return null;
            }
        }
		public void CreateHierarchy() {
			#if UNITY_EDITOR
			foreach (AudioClip clip in clips) {
				string clipPath = UnityEditor.AssetDatabase.GetAssetPath(clip).GetRange("Assets/Resources/".Length);
				string clipDirectory = Path.GetDirectoryName(clipPath);
				GameObject parent = GetOrAddFolder(clipDirectory);
				GameObject child = GameObject.Find(clip.name);
				
				if (child == null) {
					child = new GameObject(clip.name);
					PureDataSetup setup = child.GetOrAddComponent<PureDataSetup>();
					
					setup.name = clip.name;
					setup.Info = pureData.infoManager.GetInfo(clip.name);
					setup.pureData = pureData;
					setup.FreezeTransform();
				}
				child.transform.parent = parent.transform;
				child.transform.Reset();
			}
			#endif
		}
Example #5
0
            public static void syncNode(ref uint availableSyncOperations, GameObject nodeGameObject, uint nodeHandle, GameObject voxelTerrainGameObject)
			{
                OctreeNode octreeNode = nodeGameObject.GetComponent<OctreeNode>();
                CuOctreeNode cuOctreeNode = CubiquityDLL.GetOctreeNode(nodeHandle);

                ////////////////////////////////////////////////////////////////////////////////
                // Has anything in this node or its children changed? If so, we may need to syncronise the node's properties, mesh and
                // structure. Each of these can be tested against a timestamp. We may also need to do this recursively on child nodes.
                ////////////////////////////////////////////////////////////////////////////////
                if (cuOctreeNode.nodeOrChildrenLastChanged > octreeNode.nodeAndChildrenLastSynced)
                {
                    bool resyncedProperties = false; // See comments where this is tested - it's a bit of a hack

                    ////////////////////////////////////////////////////////////////////////////////
                    // 1st test - Have the properties of the node changed?
                    ////////////////////////////////////////////////////////////////////////////////
                    if (cuOctreeNode.propertiesLastChanged > octreeNode.propertiesLastSynced)
                    {
                        octreeNode.renderThisNode = cuOctreeNode.renderThisNode != 0;
                        octreeNode.height = cuOctreeNode.height;
                        octreeNode.propertiesLastSynced = CubiquityDLL.GetCurrentTime();
                        resyncedProperties = true;
                    }

                    ////////////////////////////////////////////////////////////////////////////////
                    // 2nd test - Has the mesh changed and do we have time to syncronise it?
                    ////////////////////////////////////////////////////////////////////////////////
                    if ((cuOctreeNode.meshLastChanged > octreeNode.meshLastSynced) && (availableSyncOperations > 0))
                    {
                        if (cuOctreeNode.hasMesh == 1)
                        {
                            // Set up the rendering mesh											
                            VolumeRenderer volumeRenderer = voxelTerrainGameObject.GetComponent<VolumeRenderer>();
                            if (volumeRenderer != null)
                            {
                                MeshFilter meshFilter = nodeGameObject.GetOrAddComponent<MeshFilter>() as MeshFilter;
                                if(meshFilter.sharedMesh == null)
                                {
                                    meshFilter.sharedMesh = new Mesh();
                                }
                                MeshRenderer meshRenderer = nodeGameObject.GetOrAddComponent<MeshRenderer>() as MeshRenderer;

                                if (voxelTerrainGameObject.GetComponent<Volume>().GetType() == typeof(TerrainVolume))
                                {
                                    MeshConversion.BuildMeshFromNodeHandleForTerrainVolume(meshFilter.sharedMesh, nodeHandle, false);
                                }
                                else if (voxelTerrainGameObject.GetComponent<Volume>().GetType() == typeof(ColoredCubesVolume))
                                {
                                    MeshConversion.BuildMeshFromNodeHandleForColoredCubesVolume(meshFilter.sharedMesh, nodeHandle, false);
                                }

                                meshRenderer.enabled = volumeRenderer.enabled && octreeNode.renderThisNode;

                                // For syncing materials, shadow properties, etc.
                                syncNodeWithVolumeRenderer(nodeGameObject, volumeRenderer, false);
                            }

                            // Set up the collision mesh
                            VolumeCollider volumeCollider = voxelTerrainGameObject.GetComponent<VolumeCollider>();
                            if (volumeCollider != null)
                            {
                                bool useCollider = volumeCollider.useInEditMode || Application.isPlaying;

                                if (useCollider)
                                {
                                    // I'm not quite comfortable with this. For some reason we have to create this new mesh, fill it,
                                    // and set it as the collider's shared mesh, whereas I would rather just pass the collider's sharedMesh
                                    // straight to the functon that fills it. For some reason that doesn't work properly, and we see
                                    // issues with objects falling through terrain or not updating when part of the terrain is deleted.
                                    // It's to be investigated further... perhaps we could try deleting and recreating the MeshCollider?
                                    // Still, the approach below seems to work properly.
                                    Mesh collisionMesh = new Mesh();
                                    if (voxelTerrainGameObject.GetComponent<Volume>().GetType() == typeof(TerrainVolume))
                                    {
                                        MeshConversion.BuildMeshFromNodeHandleForTerrainVolume(collisionMesh, nodeHandle, true);
                                    }
                                    else if (voxelTerrainGameObject.GetComponent<Volume>().GetType() == typeof(ColoredCubesVolume))
                                    {
                                        MeshConversion.BuildMeshFromNodeHandleForColoredCubesVolume(collisionMesh, nodeHandle, true);
                                    }

                                    MeshCollider meshCollider = nodeGameObject.GetOrAddComponent<MeshCollider>() as MeshCollider;
                                    meshCollider.sharedMesh = collisionMesh;
                                }
                            }
                        }
                        // If there is no mesh in Cubiquity then we make sure there isn't one in Unity.
                        else
                        {
                            MeshCollider meshCollider = nodeGameObject.GetComponent<MeshCollider>() as MeshCollider;
                            if (meshCollider)
                            {
                                Utility.DestroyOrDestroyImmediate(meshCollider);
                            }

                            MeshRenderer meshRenderer = nodeGameObject.GetComponent<MeshRenderer>() as MeshRenderer;
                            if (meshRenderer)
                            {
                                Utility.DestroyOrDestroyImmediate(meshRenderer);
                            }

                            MeshFilter meshFilter = nodeGameObject.GetComponent<MeshFilter>() as MeshFilter;
                            if (meshFilter)
                            {
                                Utility.DestroyOrDestroyImmediate(meshFilter);
                            }
                        }

                        octreeNode.meshLastSynced = CubiquityDLL.GetCurrentTime();
                        availableSyncOperations--;
                    }

                    // We want to syncronize the properties before the mesh, so that the enabled flag can be set correctly when the mesh
                    // is created. But we also want to syncronize properties after the mesh, so we can apply the correct enabled flag to
                    // existing meshes when the node's 'renderThisNode' flag has changed. Therefore we set the 'resyncedProperties' flag
                    // previously to let ourseves know that we should come back an finish the propertiy syncing here. It's a bit of a hack.
                    if (resyncedProperties)
                    {
                        VolumeRenderer volumeRenderer = voxelTerrainGameObject.GetComponent<VolumeRenderer>();
                        if(volumeRenderer != null)
                        {
                            syncNodeWithVolumeRenderer(nodeGameObject, volumeRenderer, false);
                        }

                        VolumeCollider volumeCollider = voxelTerrainGameObject.GetComponent<VolumeCollider>();
                        if (volumeCollider != null)
                        {
                            syncNodeWithVolumeCollider(nodeGameObject, volumeCollider, false);
                        }
                    }

                    uint[, ,] childHandleArray = new uint[2, 2, 2];
                    childHandleArray[0, 0, 0] = cuOctreeNode.childHandle000;
                    childHandleArray[0, 0, 1] = cuOctreeNode.childHandle001;
                    childHandleArray[0, 1, 0] = cuOctreeNode.childHandle010;
                    childHandleArray[0, 1, 1] = cuOctreeNode.childHandle011;
                    childHandleArray[1, 0, 0] = cuOctreeNode.childHandle100;
                    childHandleArray[1, 0, 1] = cuOctreeNode.childHandle101;
                    childHandleArray[1, 1, 0] = cuOctreeNode.childHandle110;
                    childHandleArray[1, 1, 1] = cuOctreeNode.childHandle111;

                    ////////////////////////////////////////////////////////////////////////////////
                    // 3rd test - Has the structure of the octree node changed (gained or lost children)?
                    ////////////////////////////////////////////////////////////////////////////////
                    if (cuOctreeNode.structureLastChanged > octreeNode.structureLastSynced)
                    {
                        //Now syncronise any children
                        for (uint z = 0; z < 2; z++)
                        {
                            for (uint y = 0; y < 2; y++)
                            {
                                for (uint x = 0; x < 2; x++)
                                {
                                    if (childHandleArray[x, y, z] != 0xFFFFFFFF)
                                    {
                                        uint childNodeHandle = childHandleArray[x, y, z];

                                        if (octreeNode.GetChild(x, y, z) == null)
                                        {
                                            octreeNode.SetChild(x, y, z, OctreeNode.CreateOctreeNode(childNodeHandle, nodeGameObject));
                                        }
                                    }
                                    else
                                    {
                                        if (octreeNode.GetChild(x, y, z))
                                        {
                                            Utility.DestroyOrDestroyImmediate(octreeNode.GetChild(x, y, z));
                                            octreeNode.SetChild(x, y, z, null);
                                        }
                                    }
                                }
                            }
                        }

                        octreeNode.structureLastSynced = CubiquityDLL.GetCurrentTime();
                    }

                    ////////////////////////////////////////////////////////////////////////////////
                    // The last step of syncronization is to apply it recursively to our children.
                    ////////////////////////////////////////////////////////////////////////////////
                    for (uint z = 0; z < 2; z++)
                    {
                        for (uint y = 0; y < 2; y++)
                        {
                            for (uint x = 0; x < 2; x++)
                            {
                                if (octreeNode.GetChild(x, y, z) != null && availableSyncOperations > 0)
                                {
                                    OctreeNode.syncNode(ref availableSyncOperations, octreeNode.GetChild(x, y, z), childHandleArray[x, y, z], voxelTerrainGameObject);
                                }
                            }
                        }
                    }

                    // We've reached the end of our syncronization process. If there are still sync operations available then
                    // we did less work then we could have, which implies we finished. Therefore mark the whole tree as synced.
                    if (availableSyncOperations > 0)
                    {
                        octreeNode.nodeAndChildrenLastSynced = CubiquityDLL.GetCurrentTime();
                    }
                }
			}
        void GenerateSphereCollider(GameObject boneCollider, Vector2[] points)
        {
            float l = float.MaxValue;
            float r = float.MinValue;
            float d = float.MaxValue;
            float u = float.MinValue;

            for (int i = 0; i < points.Length; i++) {
                if (points[i].x < l) {
                    l = points[i].x;
                }

                if (points[i].x > r) {
                    r = points[i].x;
                }

                if (points[i].y < d) {
                    d = points[i].y;
                }

                if (points[i].y > u) {
                    u = points[i].y;
                }
            }

            float radius = Mathf.Max(Mathf.Abs(l - r), Mathf.Abs(d - u)) / 2 * physicsOptions.colliderSize;
            if (radius >= 0.001F) {
                SphereCollider sphere = boneCollider.GetOrAddComponent<SphereCollider>();
                sphere.radius = radius;
                sphere.center = new Vector3(l + r, u + d, 0) / 2;
            }
        }
        void GeneratePolygonCollider2D(GameObject boneCollider, Vector2[] points)
        {
            float previousPointDistanceMultiplier = Random.Range(0.5F, 2F);
            float centerDistanceMultiplier = Random.Range(0.5F, 2F);
            float wrongDirectionMultiplier = Random.Range(0.5F, 2F);
            float minDistance = Random.Range(0.001F, 0.1F);

            List<Vector2> path = new List<Vector2>();
            List<Vector2> remainingPoints = new List<Vector2>(points);

            // Find center point
            Vector2 centerPoint = Vector2.zero;

            foreach (Vector2 point in points) {
                centerPoint += point;
            }

            centerPoint /= points.Length;

            // Find first point
            Vector2 firstPoint = new Vector2(float.MaxValue, 0);

            foreach (Vector2 point in remainingPoints) {
                if (point.x < firstPoint.x) {
                    firstPoint = point;
                }
            }

            path.Add(remainingPoints.Pop(firstPoint));

            // Going up-left
            Vector2 bestPoint = -firstPoint;

            while (true) {
                float bestScore = float.MaxValue;
                bestPoint = firstPoint;

                for (int i = remainingPoints.Count - 1; i >= 0; i--) {
                    Vector2 point = remainingPoints[i];
                    float distanceFromPreviousPoint = Vector2.Distance(point, path.Last());

                    if (distanceFromPreviousPoint < minDistance) {
                        remainingPoints.Remove(point);
                    }
                    else if (point.y > path.Last().y) {
                        float score = Vector2.Distance(point, path.Last()) * previousPointDistanceMultiplier;
                        score -= Vector2.Distance(point, centerPoint) * centerDistanceMultiplier;
                        score += point.x - path.Last().x * wrongDirectionMultiplier;

                        if (score < bestScore) {
                            bestScore = score;
                            bestPoint = point;
                        }
                    }
                }

                if (bestPoint == firstPoint) {
                    break;
                }

                path.Add(remainingPoints.Pop(bestPoint));
            }

            // Going right-up
            bestPoint = -firstPoint;

            while (true) {
                float bestScore = float.MaxValue;
                bestPoint = firstPoint;

                for (int i = remainingPoints.Count - 1; i >= 0; i--) {
                    Vector2 point = remainingPoints[i];
                    float distanceFromPreviousPoint = Vector2.Distance(point, path.Last());

                    if (distanceFromPreviousPoint < minDistance) {
                        remainingPoints.Remove(point);
                    }
                    else if (point.x > path.Last().x) {
                        float score = Vector2.Distance(point, path.Last()) * previousPointDistanceMultiplier;
                        score -= Vector2.Distance(point, centerPoint) * centerDistanceMultiplier;
                        score += path.Last().y - point.y * wrongDirectionMultiplier;

                        if (score < bestScore) {
                            bestScore = score;
                            bestPoint = point;
                        }
                    }
                }

                if (bestPoint == firstPoint) {
                    break;
                }

                path.Add(remainingPoints.Pop(bestPoint));
            }

            // Going down-right
            bestPoint = -firstPoint;

            while (true) {
                float bestScore = float.MaxValue;
                bestPoint = firstPoint;

                for (int i = remainingPoints.Count - 1; i >= 0; i--) {
                    Vector2 point = remainingPoints[i];
                    float distanceFromPreviousPoint = Vector2.Distance(point, path.Last());

                    if (distanceFromPreviousPoint < minDistance) {
                        remainingPoints.Remove(point);
                    }
                    else if (point.y < path.Last().y) {
                        float score = Vector2.Distance(point, path.Last()) * previousPointDistanceMultiplier;
                        score -= Vector2.Distance(point, centerPoint) * centerDistanceMultiplier;
                        score += path.Last().x - point.x * wrongDirectionMultiplier;
                        if (score < bestScore) {
                            bestScore = score;
                            bestPoint = point;
                        }
                    }
                }

                if (bestPoint == firstPoint) {
                    break;
                }

                path.Add(remainingPoints.Pop(bestPoint));
            }

            // Going left-down
            bestPoint = -firstPoint;

            while (true) {
                float bestScore = float.MaxValue;
                bestPoint = firstPoint;

                for (int i = remainingPoints.Count - 1; i >= 0; i--) {
                    Vector2 point = remainingPoints[i];
                    float distanceFromPreviousPoint = Vector2.Distance(point, path.Last());

                    if (distanceFromPreviousPoint < minDistance) {
                        remainingPoints.Remove(point);
                    }
                    else if (point.x < path.Last().x) {
                        float score = distanceFromPreviousPoint * previousPointDistanceMultiplier;
                        score -= Vector2.Distance(point, centerPoint) * centerDistanceMultiplier;
                        score += point.y - path.Last().y * wrongDirectionMultiplier;

                        if (score < bestScore) {
                            bestScore = score;
                            bestPoint = point;
                        }
                    }
                }

                if (bestPoint == firstPoint) {
                    break;
                }

                path.Add(remainingPoints.Pop(bestPoint));
            }

            if (path.Count > 2) {
                PolygonCollider2D polygon2D = boneCollider.GetOrAddComponent<PolygonCollider2D>();
                polygon2D.SetPath(0, path.ToArray());
            }
        }
        void GenerateCircleCollider2D(GameObject boneCollider, Vector2[] points)
        {
            float l = float.MaxValue;
            float r = float.MinValue;
            float d = float.MaxValue;
            float u = float.MinValue;

            for (int i = 0; i < points.Length; i++) {
                if (points[i].x < l) {
                    l = points[i].x;
                }

                if (points[i].x > r) {
                    r = points[i].x;
                }

                if (points[i].y < d) {
                    d = points[i].y;
                }

                if (points[i].y > u) {
                    u = points[i].y;
                }
            }

            float radius = Mathf.Max(Mathf.Abs(l - r), Mathf.Abs(d - u)) / 2 * physicsOptions.colliderSize;
            if (radius >= 0.001F) {
                CircleCollider2D circle2D = boneCollider.GetOrAddComponent<CircleCollider2D>();
                circle2D.radius = radius;
                circle2D.offset = new Vector2(l + r, u + d) / 2;
            }
        }
        void GenerateBoxCollider2D(GameObject boneCollider, Vector2[] points)
        {
            float l = float.MaxValue;
            float r = float.MinValue;
            float d = float.MaxValue;
            float u = float.MinValue;

            for (int i = 0; i < points.Length; i++) {
                if (points[i].x < l) {
                    l = points[i].x;
                }

                if (points[i].x > r) {
                    r = points[i].x;
                }

                if (points[i].y < d) {
                    d = points[i].y;
                }

                if (points[i].y > u) {
                    u = points[i].y;
                }
            }

            Vector2 size = new Vector2(Mathf.Abs(l - r), Mathf.Abs(d - u)) * physicsOptions.colliderSize;
            if (size.x >= 0.055F || size.y >= 0.055F) {
                BoxCollider2D box2D = boneCollider.GetOrAddComponent<BoxCollider2D>();
                box2D.size = new Vector2(Mathf.Max(size.x, 0.055F), Mathf.Max(size.y, 0.055F));
                box2D.offset = new Vector2(l + r, u + d) / 2;
            }
        }
        void GenerateBoxCollider(GameObject boneCollider, Vector2[] points)
        {
            float l = float.MaxValue;
            float r = float.MinValue;
            float d = float.MaxValue;
            float u = float.MinValue;

            for (int i = 0; i < points.Length; i++) {
                if (points[i].x < l) {
                    l = points[i].x;
                }

                if (points[i].x > r) {
                    r = points[i].x;
                }

                if (points[i].y < d) {
                    d = points[i].y;
                }

                if (points[i].y > u) {
                    u = points[i].y;
                }
            }

            Vector3 size = new Vector3(Mathf.Abs(l - r), Mathf.Abs(d - u), 1) * physicsOptions.colliderSize;
            if (size.x >= 0.001F || size.y >= 0.001F) {
                BoxCollider box = boneCollider.GetOrAddComponent<BoxCollider>();
                box.size = new Vector2(Mathf.Max(size.x, 0.001F), Mathf.Max(size.y, 0.001F));
                box.center = new Vector2(l + r, u + d) / 2;
                box.sharedMaterial = physicsOptions.colliderMaterial;
            }
        }
        public static void SerializeGameObjectReference(Stream stream, GameObject value)
        {
            if (value == null)
            {
                Basic.WriteByte(stream, 0);
                return;
            }

            var prefabId = PrefabStorage.Current.GetIndex(value);
            if (prefabId != -1)
            {
                Basic.WriteByte(stream, 1);
                Write(stream, prefabId);
            }
            else
            {
                Basic.WriteByte(stream, 2);
                int refId = value.GetOrAddComponent<FSReference>().GetPersistentId();
                Write(stream, refId);
            }
        }