/// <summary> /// Add action doors to parent transform. /// </summary> private void AddActionDoors() { GameObject actionDoorsNode = new GameObject("Action Doors"); actionDoorsNode.transform.parent = this.transform; foreach (DFBlock.RmbBlockDoorRecord obj in recordData.Interior.BlockDoorRecords) { // Get model transform Vector3 modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0); Vector3 modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale; // Instantiate door prefab and add model GameObject go = GameObjectHelper.InstantiatePrefab(dfUnity.Option_InteriorDoorPrefab.gameObject, string.Empty, actionDoorsNode.transform, Vector3.zero); GameObjectHelper.CreateDaggerfallMeshGameObject(doorModelId, actionDoorsNode.transform, false, go, true); // Resize box collider to new mesh bounds BoxCollider boxCollider = go.GetComponent <BoxCollider>(); MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>(); if (boxCollider != null && meshRenderer != null) { boxCollider.center = meshRenderer.bounds.center; boxCollider.size = meshRenderer.bounds.size; } // Apply transforms go.transform.rotation = Quaternion.Euler(modelRotation); go.transform.position = modelPosition; } }
/// <summary> /// Add action doors to parent transform. /// </summary> private void AddActionDoors() { GameObject node = new GameObject("ActionDoors"); node.transform.parent = this.transform; foreach (DFBlock.RmbBlockDoorRecord obj in recordData.Interior.BlockDoorRecords) { // Get model transform Vector3 modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0); Vector3 modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale; // Add GameObject GameObject go = GameObjectHelper.CreateDaggerfallMeshGameObject(doorModelId, node.transform); go.transform.rotation = Quaternion.Euler(modelRotation); go.transform.position = modelPosition; // Add component DaggerfallActionDoor c = go.AddComponent <DaggerfallActionDoor>(); c.OpenAngle = -obj.OpenRotation; // Add sounds if (dfUnity.Option_DefaultSounds) { go.AddComponent <DaggerfallAudioSource>(); c.SetInteriorDoorSounds(); } } }
/// <summary> /// Add action doors to parent transform. /// </summary> private void AddActionDoors() { // Using 9000-9005 here but identical door models are also found at 900x, 910x, through to 980x // They seem to be duplicate models but can have different model origins so not all ranges are suitable const int doorModelBaseId = 9000; GameObject actionDoorsNode = new GameObject("Action Doors"); actionDoorsNode.transform.parent = this.transform; foreach (DFBlock.RmbBlockDoorRecord obj in recordData.Interior.BlockDoorRecords) { // Create unique LoadID for save sytem ulong loadID = (ulong)(blockData.Position + obj.Position); // Get model transform Vector3 modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0); Vector3 modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale; // Instantiate door prefab and add model - DoorModelIndex is modulo to known-good range just in case uint modelId = (uint)(doorModelBaseId + obj.DoorModelIndex % 5); GameObject go = GameObjectHelper.InstantiatePrefab(dfUnity.Option_InteriorDoorPrefab.gameObject, string.Empty, actionDoorsNode.transform, Vector3.zero); GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, actionDoorsNode.transform, false, go, true); // Resize box collider to new mesh bounds BoxCollider boxCollider = go.GetComponent <BoxCollider>(); MeshRenderer meshRenderer = go.GetComponent <MeshRenderer>(); if (boxCollider != null && meshRenderer != null) { boxCollider.center = meshRenderer.bounds.center; boxCollider.size = meshRenderer.bounds.size; } // Apply transforms go.transform.rotation = Quaternion.Euler(modelRotation); go.transform.position = modelPosition; // Update climate DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>(); dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled); // Get action door script DaggerfallActionDoor actionDoor = go.GetComponent <DaggerfallActionDoor>(); // Assign loadID if (actionDoor) { actionDoor.LoadID = loadID; } if (SaveLoadManager.Instance != null) { go.AddComponent <SerializableActionDoor>(); } } }
private static void PlaceWagon(bool fromSave = false) { if (fromSave == false) { WagonMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel; if (!transportManager.HasHorse()) { SetWagonPositionAndRotation(true); DaggerfallUI.MessageBox("You have no horse to pull your wagon."); ItemCollection playerItems = GameManager.Instance.PlayerEntity.Items; for (int i = 0; i < playerItems.Count; i++) { DaggerfallUnityItem item = playerItems.GetItem(i); if (item != null && item.IsOfTemplate(ItemGroups.Transportation, (int)Transportation.Small_cart)) { playerItems.RemoveItem(item); } } } else { SetWagonPositionAndRotation(); } } else { PlaceWagonOnGround(); } Wagon = MeshReplacement.ImportCustomGameobject(wagonModelID, null, WagonMatrix); if (Wagon == null) { Wagon = GameObjectHelper.CreateDaggerfallMeshGameObject(wagonModelID, null); } Wagon.transform.SetPositionAndRotation(WagonPosition, WagonRotation); if (GameManager.Instance.PlayerEnterExit.IsPlayerInsideDungeon) { Wagon.SetActive(false); } else { Wagon.SetActive(true); } WagonDeployed = true; }
private static void DeployTent(bool fromSave = false) { if (fromSave == false) { TentMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel; SetTentPositionAndRotation(); } //Attempt to load a model replacement Tent = MeshReplacement.ImportCustomGameobject(tentModelID, null, TentMatrix); if (Tent == null) { Tent = GameObjectHelper.CreateDaggerfallMeshGameObject(tentModelID, null); } //Set the model's position in the world Tent.transform.SetPositionAndRotation(TentPosition, TentRotation); Tent.SetActive(true); TentDeployed = true; }
public static void DeployTent(bool fromSave = false) { if (fromSave == false) { CampMapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel; SetTentPositionAndRotation(); DaggerfallUI.MessageBox("You set up camp"); } else { PlaceTentOnGround(); } //Attempt to load a model replacement Tent = MeshReplacement.ImportCustomGameobject(tentModelID, null, TentMatrix); Fire = GameObjectHelper.CreateDaggerfallBillboardGameObject(210, 1, null); if (Tent == null) { Tent = GameObjectHelper.CreateDaggerfallMeshGameObject(tentModelID, null); } //Set the model's position in the world Tent.transform.SetPositionAndRotation(TentPosition, TentRotation); if (GameManager.Instance.PlayerEnterExit.IsPlayerInsideDungeon) { FirePosition = Tent.transform.position + (Tent.transform.up * 0.8f); Tent.SetActive(false); } else { FirePosition = Tent.transform.position + (Tent.transform.forward * 3) + (Tent.transform.up * 0.8f); Tent.SetActive(true); } Fire.transform.SetPositionAndRotation(FirePosition, TentRotation); Fire.SetActive(true); AddTorchAudioSource(Fire); GameObject lightsNode = new GameObject("Lights"); lightsNode.transform.parent = Fire.transform; AddLight(DaggerfallUnity.Instance, Fire, lightsNode.transform); CampDeployed = true; FireLit = true; }
/// <summary> /// Add a standalone model when not combining. /// </summary> private static GameObject AddStandaloneModel( DaggerfallUnity dfUnity, ref ModelData modelData, Matrix4x4 matrix, Transform parent, bool overrideStatic = false, bool ignoreCollider = false) { // Determine static flag bool makeStatic = (dfUnity.Option_SetStaticFlags && !overrideStatic) ? true : false; // Add GameObject uint modelID = (uint)modelData.DFMesh.ObjectId; GameObject go = GameObjectHelper.CreateDaggerfallMeshGameObject(modelID, parent, makeStatic, null, ignoreCollider); go.transform.position = matrix.GetColumn(3); go.transform.rotation = GameObjectHelper.QuaternionFromMatrix(matrix); return(go); }
private void Display3dModelSelection(int selectedIdx) { if (goModel) { Object.Destroy(goModel); goModel = null; } // Position camera and set model id uint modelId = 0; if (housesForSale == null) { camera.transform.position = new Vector3(0, 12, DaggerfallBankManager.GetShipCameraDist((ShipType)selectedIdx)); modelId = DaggerfallBankManager.GetShipModelId((ShipType)selectedIdx); } else { camera.transform.position = new Vector3(0, 3, -20); BuildingSummary house = housesForSale[selectedIdx]; modelId = house.ModelID; } // Inject custom GameObject if available else create standard mesh game object for the model goModel = MeshReplacement.ImportCustomGameobject(modelId, goBankPurchase.transform, new Matrix4x4()); if (goModel == null) { goModel = GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, goBankPurchase.transform); } goModel.layer = layer; // Apply current climate ClimateBases climateBase = ClimateSwaps.FromAPIClimateBase(GameManager.Instance.PlayerGPS.ClimateSettings.ClimateType); ClimateSeason season = (DaggerfallUnity.WorldTime.Now.SeasonValue == DaggerfallDateTime.Seasons.Winter) ? ClimateSeason.Winter : ClimateSeason.Summer; DaggerfallMesh dfMesh = goModel.GetComponent <DaggerfallMesh>(); dfMesh.SetClimate(climateBase, season, WindowStyle.Day); }
public static GameObject Add3dObject(DFBlock.RdbObject obj, ref DFBlock.RdbModelReference[] modelReferenceList) { DaggerfallUnity dfUnity = DaggerfallUnity.Instance; // Get model reference index and id int modelReference = obj.Resources.ModelResource.ModelIndex; uint modelId = modelReferenceList[modelReference].ModelIdNum; // Get matrix Vector3 modelRotation = new Vector3(-obj.Resources.ModelResource.XRotation / BlocksFile.RotationDivisor, -obj.Resources.ModelResource.YRotation / BlocksFile.RotationDivisor, -obj.Resources.ModelResource.ZRotation / BlocksFile.RotationDivisor); Vector3 modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale; Matrix4x4 modelMatrix = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one); // Get model data ModelData modelData; dfUnity.MeshReader.GetModelData(modelId, out modelData); // Get GameObject GameObject modelGO = MeshReplacement.ImportCustomGameobject(modelId, null, modelMatrix, false); if (modelGO == null) { if (modelData.DFMesh.TotalVertices != 0) { modelGO = GameObjectHelper.CreateDaggerfallMeshGameObject(modelId, null); modelGO.transform.position = modelMatrix.GetColumn(3); modelGO.transform.rotation = modelMatrix.rotation; modelGO.transform.localScale = modelMatrix.lossyScale; } else { Debug.LogError("Custom model not found for modelId " + modelId); } } return(modelGO); }
public static GameObject Preview3dObject(string modelId, Vector3 position) { // Get matrix Matrix4x4 matrix = Matrix4x4.identity; matrix *= Matrix4x4.TRS(position, Quaternion.identity, Vector3.one); // Get model data uint modelIdNum = uint.Parse(modelId); ModelData modelData; DaggerfallUnity.Instance.MeshReader.GetModelData(modelIdNum, out modelData); if (modelData.DFMesh.TotalVertices != 0) { GameObject modelGO = GameObjectHelper.CreateDaggerfallMeshGameObject(modelIdNum, null); modelGO.transform.position = matrix.GetColumn(3); modelGO.name = "Model Preview: " + modelId; return(modelGO); } Debug.LogWarning("Vanilla model not found for preview, modelId " + modelId); return(null); }
public void UpdateMarkers(bool RemoveMarkersOnly = false) { foreach (GameObject marker in buildingInfoCollection) { if (marker.GetComponent <BuildingMarker>() != null) { BuildingMarker markerInstance = marker.GetComponent <BuildingMarker>(); Destroy(markerInstance.marker.attachedDoorIcon); Destroy(markerInstance.marker.attachedLabel); Destroy(markerInstance.marker.attachedMesh); Destroy(markerInstance.marker.attachedQuestIcon); Destroy(markerInstance.marker.attachedIcon); Destroy(markerInstance); } if (marker != null) { Destroy(marker); } } buildingInfoCollection.Clear(); buildingInfoCollection = new List <GameObject>(); if (RemoveMarkersOnly) { return; } generatingMarkers = true; //Vector3 position = currentCityNav.WorldToScenePosition(new DFPosition(Minimap.currentLocation.Summary.MapPixelX, Minimap.currentLocation.Summary.MapPixelX), true); List <BuildingSummary> housesForSaleList = buildingDirectory.GetHousesForSale(); foreach (DaggerfallRMBBlock block in blockArray) { Vector3 blockPosition = block.transform.position; //setup a new static buildings object to hold the rmb blocks static buildings object. DaggerfallStaticBuildings staticBuildingContainer = block.GetComponentInChildren <DaggerfallStaticBuildings>(); //if there are not any buildings in this block, stop code from crashing script and return. if (staticBuildingContainer == null) { continue; } //resize static building array based on the number of static building pbjects in the container. StaticBuildingArray = new StaticBuilding[staticBuildingContainer.transform.childCount]; //load blocks static building array into the empty array for looping through. StaticBuildingArray = staticBuildingContainer.Buildings; // Find the doors for the buildings and drop into a list for referencing below when setting up individual building information. StaticDoor[] doors = DaggerfallStaticDoors.FindDoorsInCollections(GameManager.Instance.StreamingWorld.CurrentPlayerLocationObject.StaticDoorCollections, DoorTypes.Building); List <CombineInstance> houseMeshList = new List <CombineInstance>(); //runs through building array. foreach (StaticBuilding building in StaticBuildingArray) { //sets up and grabes the current buildings material, summary object/info, placing/final position, game model. BuildingSummary SavedBuilding = new BuildingSummary(); buildingDirectory.GetBuildingSummary(building.buildingKey, out SavedBuilding); if (SavedBuilding.BuildingType == DFLocation.BuildingTypes.AllValid) { continue; } Vector3 markerPosition = new Vector3(0, 0, 0); if (building.size.z > tallestSpot) { tallestSpot = building.size.z; } //create gameobject for building marker. GameObject buildingMarkerObject = GameObjectHelper.CreateDaggerfallMeshGameObject(SavedBuilding.ModelID, null, false, null, true, false); buildingMarkerObject.GetComponent <Renderer>().enabled = false; buildingMarkerObject.transform.position = new Vector3(blockPosition.x + SavedBuilding.Position.x, blockPosition.y + tallestSpot + 10f, blockPosition.z + SavedBuilding.Position.z); //buildingMarkerObject.SetActive(false); BuildingMarker buildingsInfo = buildingMarkerObject.AddComponent <BuildingMarker>(); MeshRenderer buildingMesh = buildingMarkerObject.GetComponent <MeshRenderer>(); buildingsInfo.marker.attachedMesh = buildingMarkerObject; buildingMarkerObject.transform.position = buildingMarkerObject.transform.position; buildingMarkerObject.transform.Rotate(SavedBuilding.Rotation); buildingMarkerObject.layer = Minimap.layerMinimap; buildingMarkerObject.transform.localScale = new Vector3(1, 0.01f, 1); buildingMarkerObject.name = string.Concat(SavedBuilding.BuildingType.ToString(), " Marker ", SavedBuilding.buildingKey); buildingMesh.shadowCastingMode = 0; buildingMesh.lightProbeUsage = UnityEngine.Rendering.LightProbeUsage.Off; buildingMesh.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion; //Destroy(buildingMarkerObject.GetComponent<MeshCollider>()); //grab and store all building info into the building marker object. buildingsInfo.marker.staticBuilding = building; buildingsInfo.marker.buildingSummary = SavedBuilding; buildingsInfo.marker.buildingKey = SavedBuilding.buildingKey; foreach (BuildingSummary buildingInfo in housesForSaleList) { if (buildingInfo.BuildingType == DFLocation.BuildingTypes.HouseForSale) { buildingsInfo.marker.buildingType = DFLocation.BuildingTypes.HouseForSale; } else { buildingsInfo.marker.buildingType = SavedBuilding.BuildingType; } } buildingsInfo.marker.buildingLocation = GameManager.Instance.PlayerGPS.CurrentLocation; //buildingPositionList.Add(new Vector3(block.transform.position.x + SavedBuilding.Position.x, SavedBuilding.Position.y, block.transform.position.z + SavedBuilding.Position.z)); buildingsInfo.marker.position = buildingMarkerObject.transform.position; foreach (StaticDoor buildingsDoor in doors) { if (building.buildingKey == buildingsDoor.buildingKey) { buildingsInfo.marker.doorPosition = DaggerfallStaticDoors.GetDoorPosition(buildingsDoor); } } //setup ref properties for quest resource locator below. bool pcLearnedAboutExistence = false; bool receivedDirectionalHints = false; bool locationWasMarkedOnMapByNPC = false; string overrideBuildingName = string.Empty; //check if the building contains a quest using quest resouces. If found to contain a quest, mark it so. if (GameManager.Instance.TalkManager.IsBuildingQuestResource(GameManager.Instance.PlayerGPS.CurrentMapID, buildingsInfo.marker.buildingKey, ref overrideBuildingName, ref pcLearnedAboutExistence, ref receivedDirectionalHints, ref locationWasMarkedOnMapByNPC)) { Minimap.lastQuestMarkerPosition = buildingsInfo.marker.position; buildingsInfo.marker.questActive = true; } //save building to building collection. This is more for other modders to use how they wish, since it contains all the building info for every building in a city. buildingInfoCollection.Add(buildingMarkerObject); } } markersGenerated = true; }
private void DisplayImporterGUI() { // Hide importer GUI when not active in hierarchy if (!dfUnity.gameObject.activeInHierarchy) { return; } EditorGUILayout.Space(); ShowImportFoldout = GUILayoutHelper.Foldout(ShowImportFoldout, new GUIContent("Importer"), () => { GUILayoutHelper.Indent(() => { EditorGUILayout.Space(); var propModelID = Prop("ModelImporter_ModelID"); EditorGUILayout.LabelField(new GUIContent("ModelID", "Enter numeric ID of model.")); GUILayoutHelper.Horizontal(() => { propModelID.intValue = EditorGUILayout.IntField(propModelID.intValue); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallMeshGameObject((uint)propModelID.intValue, null); } }); EditorGUILayout.Space(); var propBlockName = Prop("BlockImporter_BlockName"); EditorGUILayout.LabelField(new GUIContent("Block Name", "Enter name of block. Accepts .RMB and .RDB blocks.")); GUILayoutHelper.Horizontal(() => { propBlockName.stringValue = EditorGUILayout.TextField(propBlockName.stringValue.Trim().ToUpper()); if (GUILayout.Button("Import")) { // Create block if (propBlockName.stringValue.EndsWith(".RMB")) { GameObjectHelper.CreateRMBBlockGameObject(propBlockName.stringValue, dfUnity.Option_RMBGroundPlane, dfUnity.Option_CityBlockPrefab); } else if (propBlockName.stringValue.EndsWith(".RDB")) { GameObjectHelper.CreateRDBBlockGameObject( propBlockName.stringValue, null, true, DFRegion.DungeonTypes.HumanStronghold, 0.5f, 4, (int)DateTime.Now.Ticks, dfUnity.Option_DungeonBlockPrefab); } } }); EditorGUILayout.Space(); var propCityName = Prop("CityImporter_CityName"); EditorGUILayout.LabelField(new GUIContent("City Name", "Enter exact city name in format RegionName/CityName. Case-sensitive.")); GUILayoutHelper.Horizontal(() => { propCityName.stringValue = EditorGUILayout.TextField(propCityName.stringValue.Trim()); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallLocationGameObject(propCityName.stringValue, null); } }); EditorGUILayout.Space(); var propDungeonName = Prop("DungeonImporter_DungeonName"); EditorGUILayout.LabelField(new GUIContent("Dungeon Name", "Enter exact dungeon name in format RegionName/DungeonName. Case-sensitive.")); GUILayoutHelper.Horizontal(() => { propDungeonName.stringValue = EditorGUILayout.TextField(propDungeonName.stringValue.Trim()); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallDungeonGameObject(propDungeonName.stringValue, null); } }); }); }); }
private void Start() { // Setup light and shadows myLight = GetComponent <Light>(); myLight.enabled = EnableLight; forceDisableSpellLighting = !DaggerfallUnity.Settings.EnableSpellLighting; if (forceDisableSpellLighting) { myLight.enabled = false; } if (!DaggerfallUnity.Settings.EnableSpellShadows) { myLight.shadows = LightShadows.None; } initialRange = myLight.range; initialIntensity = myLight.intensity; // Setup collider myCollider = GetComponent <SphereCollider>(); myCollider.radius = ColliderRadius; // Setup rigidbody myRigidbody = GetComponent <Rigidbody>(); myRigidbody.useGravity = false; // Use payload when available if (payload != null) { // Set payload missile properties caster = payload.CasterEntityBehaviour; targetType = payload.Settings.TargetType; elementType = payload.Settings.ElementType; // Set spell billboard anims automatically from payload for mobile missiles if (targetType == TargetTypes.SingleTargetAtRange || targetType == TargetTypes.AreaAtRange) { UseSpellBillboardAnims(); } } // Setup senses if (caster != GameManager.Instance.PlayerEntityBehaviour) { enemySenses = caster.GetComponent <EnemySenses>(); } // Setup arrow if (isArrow) { // Create and orient 3d arrow goModel = GameObjectHelper.CreateDaggerfallMeshGameObject(99800, transform); Vector3 adjust; // Offset up so it comes from same place LOS check is done from if (caster != GameManager.Instance.PlayerEntityBehaviour) { CharacterController controller = caster.transform.GetComponent <CharacterController>(); adjust = caster.transform.forward * 0.6f; adjust.y += controller.height / 3; } else { // Offset forward to avoid collision with player adjust = GameManager.Instance.MainCamera.transform.forward * 0.6f; // Adjust slightly downward to match bow animation adjust.y -= 0.11f; // Adjust to the right or left to match bow animation if (!GameManager.Instance.WeaponManager.ScreenWeapon.FlipHorizontal) { adjust += GameManager.Instance.MainCamera.transform.right * 0.15f; } else { adjust -= GameManager.Instance.MainCamera.transform.right * 0.15f; } } goModel.transform.localPosition = adjust; goModel.transform.rotation = Quaternion.LookRotation(GetAimDirection()); } // Ignore missile collision with caster (this is a different check to AOE targets) if (caster) { Physics.IgnoreCollision(caster.GetComponent <Collider>(), this.GetComponent <Collider>()); } }
/// <summary> /// DaggerfallExteriorAutomapWindow script will use this to signal this script to update when automap window was pushed - TODO: check if this can done with an event (if events work with gui windows) /// </summary> public void updateAutomapStateOnWindowPush() { ContentReader.MapSummary mapSummary; DFPosition mapPixel = GameManager.Instance.PlayerGPS.CurrentMapPixel; if (!DaggerfallUnity.Instance.ContentReader.HasLocation(mapPixel.X, mapPixel.Y, out mapSummary)) { // no location found, something went wrong } location = DaggerfallUnity.Instance.ContentReader.MapFileReader.GetLocation(mapSummary.RegionIndex, mapSummary.MapIndex); if (!location.Loaded) { // Location not loaded, something went wrong } // Get location dimensions locationWidth = location.Exterior.ExteriorData.Width; locationHeight = location.Exterior.ExteriorData.Height; // Get layout image dimensions layoutWidth = locationWidth * blockSizeWidth; layoutHeight = locationHeight * blockSizeHeight; // Create map layout switch (currentExteriorAutomapViewMode) { case ExteriorAutomapViewMode.Original: createExteriorLayoutTexture(location, false, true); break; case ExteriorAutomapViewMode.Extra: createExteriorLayoutTexture(location, true, true); break; case ExteriorAutomapViewMode.All: createExteriorLayoutTexture(location, true, false); break; } // create player marker if (!gameobjectPlayerMarkerArrow) { gameobjectPlayerMarkerArrow = GameObjectHelper.CreateDaggerfallMeshGameObject(99900, gameobjectExteriorAutomap.transform, false, null, true); gameobjectPlayerMarkerArrow.name = "PlayerMarkerArrow"; gameobjectPlayerMarkerArrow.layer = layerAutomap; Material oldMat = gameobjectPlayerMarkerArrow.GetComponent <MeshRenderer>().material; Material newMat = new Material(oldMat); newMat.shader = Shader.Find("Unlit/Texture"); //newMat.CopyPropertiesFromMaterial(oldMat); gameobjectPlayerMarkerArrow.GetComponent <MeshRenderer>().material = newMat; gameobjectPlayerMarkerArrow.transform.localScale = new Vector3(2.5f, 2.5f, 2.5f) * layoutMultiplier; } // create player marker stamp (a darkened larger version in the background) if (!gameobjectPlayerMarkerArrowStamp) { gameobjectPlayerMarkerArrowStamp = GameObjectHelper.CreateDaggerfallMeshGameObject(99900, gameobjectExteriorAutomap.transform, false, null, true); gameobjectPlayerMarkerArrowStamp.name = "PlayerMarkerArrowStamp"; gameobjectPlayerMarkerArrowStamp.layer = layerAutomap; Material oldMat = gameobjectPlayerMarkerArrowStamp.GetComponent <MeshRenderer>().material; Material newMat = new Material(oldMat); newMat.shader = Shader.Find("Unlit/Color"); newMat.color = new Color(0.353f, 0.086f, 0.086f); //newMat.CopyPropertiesFromMaterial(oldMat); gameobjectPlayerMarkerArrowStamp.GetComponent <MeshRenderer>().material = newMat; gameobjectPlayerMarkerArrowStamp.transform.localScale = new Vector3(4.0f, 4.0f, 4.0f) * layoutMultiplier; } // create player circle if (!gameobjectPlayerMarkerCircle) { gameobjectPlayerMarkerCircle = GameObject.CreatePrimitive(PrimitiveType.Cylinder); CapsuleCollider capsuleCollider = gameobjectPlayerMarkerCircle.GetComponent <CapsuleCollider>(); if (capsuleCollider) { // get rid of capsule collider UnityEngine.Object.Destroy(capsuleCollider); } gameobjectPlayerMarkerCircle.name = "PlayerMarkerCircle"; gameobjectPlayerMarkerCircle.layer = layerAutomap; gameobjectPlayerMarkerCircle.transform.SetParent(gameobjectExteriorAutomap.transform); Material oldMat = gameobjectPlayerMarkerCircle.GetComponent <MeshRenderer>().material; Material newMat = new Material(oldMat); newMat.shader = Shader.Find("Unlit/Color"); newMat.color = new Color(0.75f, 0.71f, 0.71f); //newMat.CopyPropertiesFromMaterial(oldMat); gameobjectPlayerMarkerCircle.GetComponent <MeshRenderer>().material = newMat; gameobjectPlayerMarkerCircle.transform.localScale = new Vector3(12.0f, 1.0f, 12.0f) * layoutMultiplier; } // place player marker Vector3 playerPos = (GameManager.Instance.PlayerGPS.transform.position - GameManager.Instance.StreamingWorld.WorldCompensation) / (MapsFile.WorldMapTerrainDim * MeshReader.GlobalScale); //Debug.Log(String.Format("player xpos: {0}, player ypos: {1}", playerPos.x, playerPos.z)); int refWidth = (int)(blockSizeWidth * 8 * layoutMultiplier); // layoutWidth / layoutMultiplier int refHeight = (int)(blockSizeHeight * 8 * layoutMultiplier); // layoutHeight / layoutMultiplier playerPos.x *= refWidth; playerPos.y = 0.1f; playerPos.z *= refHeight; playerPos.x -= refWidth * 0.5f; playerPos.z -= refHeight * 0.5f; gameobjectPlayerMarkerArrow.transform.position = playerPos; gameobjectPlayerMarkerArrow.transform.rotation = gameObjectPlayerAdvanced.transform.rotation; // place player marker stamp Vector3 newPos = gameobjectPlayerMarkerArrow.transform.position; newPos.y = -10.0f; Vector3 biasVec = -Vector3.Normalize(gameObjectPlayerAdvanced.transform.forward); gameobjectPlayerMarkerArrowStamp.transform.position = newPos + biasVec * 0.8f; gameobjectPlayerMarkerArrowStamp.transform.rotation = gameobjectPlayerMarkerArrow.transform.rotation; newPos.y = -20.0f; gameobjectPlayerMarkerCircle.transform.position = newPos; gameobjectPlayerMarkerCircle.transform.rotation = gameobjectPlayerMarkerArrow.transform.rotation; //byte[] png = exteriorLayoutTexture.EncodeToPNG(); //Debug.Log(String.Format("writing to folder {0}", Application.dataPath)); //File.WriteAllBytes(Application.dataPath + "/test.png", png); createCustomCanvasForExteriorAutomap(); // create camera (if not present) that will render automap level geometry createExteriorAutomapCamera(); }
/// <summary> /// Add interior models. /// </summary> private void AddModels(PlayerGPS.DiscoveredBuilding buildingData) { List <StaticDoor> doors = new List <StaticDoor>(); GameObject node = new GameObject("Models"); GameObject doorsNode = new GameObject("Doors"); node.transform.parent = this.transform; doorsNode.transform.parent = this.transform; // Iterate through models in this subrecord combiner.NewCombiner(); foreach (DFBlock.RmbBlock3dObjectRecord obj in recordData.Interior.Block3dObjectRecords) { bool stopCombine = false; // Get model data ModelData modelData; dfUnity.MeshReader.GetModelData(obj.ModelIdNum, out modelData); // Get model position by type (3 seems to indicate props/clutter) // Also stop these from being combined as some may carry a loot container Vector3 modelPosition; if (obj.ObjectType == propModelType) { // Props axis needs to be transformed to lowest Y point Vector3 bottom = modelData.Vertices[0]; for (int i = 0; i < modelData.Vertices.Length; i++) { if (modelData.Vertices[i].y < bottom.y) { bottom = modelData.Vertices[i]; } } modelPosition = new Vector3(obj.XPos, obj.YPos, obj.ZPos) * MeshReader.GlobalScale; modelPosition += new Vector3(0, -bottom.y, 0); stopCombine = true; } else { modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale; } // Stop special object from being combined if (obj.ModelIdNum == ladderModelId) { stopCombine = true; } // Get model transform Vector3 modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0); Matrix4x4 modelMatrix = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one); // Does this model have doors? if (modelData.Doors != null) { doors.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, entryDoor.blockIndex, entryDoor.recordIndex, modelMatrix)); } // Inject custom GameObject if available GameObject go = MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, node.transform, modelMatrix); // Otherwise use Daggerfall mesh - combine or add if (!go) { if (dfUnity.Option_CombineRMB && !stopCombine) { combiner.Add(ref modelData, modelMatrix); } else { // Add individual GameObject go = GameObjectHelper.CreateDaggerfallMeshGameObject(obj.ModelIdNum, node.transform, dfUnity.Option_SetStaticFlags); go.transform.position = modelMatrix.GetColumn(3); go.transform.rotation = GameObjectHelper.QuaternionFromMatrix(modelMatrix); // Update climate DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>(); dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled); } } // Make ladder collider convex if (obj.ModelIdNum == ladderModelId) { var meshCollider = go.GetComponent <MeshCollider>(); if (meshCollider) { meshCollider.convex = true; } go.AddComponent <DaggerfallLadder>(); } // Optionally add action objects to specific furniture items (e.g. loot containers), except when laying out map (buildingType=AllValid) if (obj.ObjectType == propModelType && buildingData.buildingType != DFLocation.BuildingTypes.AllValid) { AddFurnitureAction(obj, go, buildingData); } } // Add combined GameObject if (dfUnity.Option_CombineRMB) { if (combiner.VertexCount > 0) { combiner.Apply(); GameObject go = GameObjectHelper.CreateCombinedMeshGameObject(combiner, "CombinedModels", node.transform, dfUnity.Option_SetStaticFlags); // Update climate DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>(); dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled); } } // Add static doors component DaggerfallStaticDoors c = this.gameObject.AddComponent <DaggerfallStaticDoors>(); c.Doors = doors.ToArray(); }
/// <summary> /// Add interior models. /// </summary> private void AddModels() { List <StaticDoor> doors = new List <StaticDoor>(); GameObject node = new GameObject("Models"); GameObject doorsNode = new GameObject("Doors"); node.transform.parent = this.transform; doorsNode.transform.parent = this.transform; // Iterate through models in this subrecord combiner.NewCombiner(); foreach (DFBlock.RmbBlock3dObjectRecord obj in recordData.Interior.Block3dObjectRecords) { // Get model data ModelData modelData; dfUnity.MeshReader.GetModelData(obj.ModelIdNum, out modelData); // Get model position by type (3 seems to indicate props/clutter) Vector3 modelPosition; if (obj.ObjectType == 3) { // Props axis needs to be transformed to lowest Y point Vector3 bottom = modelData.Vertices[0]; for (int i = 0; i < modelData.Vertices.Length; i++) { if (modelData.Vertices[i].y < bottom.y) { bottom = modelData.Vertices[i]; } } modelPosition = new Vector3(obj.XPos, obj.YPos, obj.ZPos) * MeshReader.GlobalScale; modelPosition += new Vector3(0, -bottom.y, 0); } else { modelPosition = new Vector3(obj.XPos, -obj.YPos, obj.ZPos) * MeshReader.GlobalScale; } // Get model transform Vector3 modelRotation = new Vector3(0, -obj.YRotation / BlocksFile.RotationDivisor, 0); Matrix4x4 modelMatrix = Matrix4x4.TRS(modelPosition, Quaternion.Euler(modelRotation), Vector3.one); // Does this model have doors? if (modelData.Doors != null) { doors.AddRange(GameObjectHelper.GetStaticDoors(ref modelData, entryDoor.blockIndex, entryDoor.recordIndex, modelMatrix)); } // Get GameObject if (MeshReplacement.ImportCustomGameobject(obj.ModelIdNum, node.transform, modelMatrix) == null) { // Use Daggerfall Mesh: Combine or add if (dfUnity.Option_CombineRMB) { combiner.Add(ref modelData, modelMatrix); } else { // Add GameObject GameObject go = GameObjectHelper.CreateDaggerfallMeshGameObject(obj.ModelIdNum, node.transform, dfUnity.Option_SetStaticFlags); go.transform.position = modelMatrix.GetColumn(3); go.transform.rotation = GameObjectHelper.QuaternionFromMatrix(modelMatrix); // Update climate DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>(); dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled); } } } // Add combined GameObject if (dfUnity.Option_CombineRMB) { if (combiner.VertexCount > 0) { combiner.Apply(); GameObject go = GameObjectHelper.CreateCombinedMeshGameObject(combiner, "CombinedModels", node.transform, dfUnity.Option_SetStaticFlags); // Update climate DaggerfallMesh dfMesh = go.GetComponent <DaggerfallMesh>(); dfMesh.SetClimate(climateBase, climateSeason, WindowStyle.Disabled); } } // Add static doors component DaggerfallStaticDoors c = this.gameObject.AddComponent <DaggerfallStaticDoors>(); c.Doors = doors.ToArray(); }
private void DisplayImporterGUI() { // Hide importer GUI when not active in hierarchy if (!dfUnity.gameObject.activeInHierarchy) { return; } EditorGUILayout.Space(); ShowImportFoldout = GUILayoutHelper.Foldout(ShowImportFoldout, new GUIContent("Importer"), () => { GUILayoutHelper.Indent(() => { EditorGUILayout.Space(); var propModelID = Prop("ModelImporter_ModelID"); EditorGUILayout.LabelField(new GUIContent("ModelID", "Enter numeric ID of model.")); GUILayoutHelper.Horizontal(() => { propModelID.intValue = EditorGUILayout.IntField(propModelID.intValue); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallMeshGameObject((uint)propModelID.intValue, null); } }); EditorGUILayout.Space(); var propBlockName = Prop("BlockImporter_BlockName"); EditorGUILayout.LabelField(new GUIContent("Block Name", "Enter name of block. Accepts .RMB and .RDB blocks.")); GUILayoutHelper.Horizontal(() => { propBlockName.stringValue = EditorGUILayout.TextField(propBlockName.stringValue.Trim().ToUpper()); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallBlockGameObject(propBlockName.stringValue, null); } }); EditorGUILayout.Space(); var propCityName = Prop("CityImporter_CityName"); EditorGUILayout.LabelField(new GUIContent("City Name", "Enter exact city name in format RegionName/CityName. Case-sensitive.")); GUILayoutHelper.Horizontal(() => { propCityName.stringValue = EditorGUILayout.TextField(propCityName.stringValue.Trim()); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallLocationGameObject(propCityName.stringValue, null); } }); EditorGUILayout.Space(); var propDungeonName = Prop("DungeonImporter_DungeonName"); EditorGUILayout.LabelField(new GUIContent("Dungeon Name", "Enter exact dungeon name in format RegionName/DungeonName. Case-sensitive.")); GUILayoutHelper.Horizontal(() => { propDungeonName.stringValue = EditorGUILayout.TextField(propDungeonName.stringValue.Trim()); if (GUILayout.Button("Import")) { GameObjectHelper.CreateDaggerfallDungeonGameObject(propDungeonName.stringValue, null); } }); }); }); }
public static GameObject CreatePlacedObject(PlacedObjectData_v2 data, Transform parent, bool previewGo = false) { // Custom models like Handpainted Models have insanley different scales (< 0.0 to 200+) Set all models as a child to a parent, so // EditMode can uniformly scale properly. GameObject parentGo = new GameObject(); GameObject childGo; parentGo.transform.parent = parent; if (data.modelID == 0) { childGo = MeshReplacement.ImportCustomFlatGameobject(data.archive, data.record, Vector3.zero, parentGo.transform); if (childGo == null) { childGo = GameObjectHelper.CreateDaggerfallBillboardGameObject(data.archive, data.record, parentGo.transform); } } else { Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one); childGo = MeshReplacement.ImportCustomGameobject(data.modelID, parentGo.transform, matrix); if (childGo == null) { childGo = GameObjectHelper.CreateDaggerfallMeshGameObject(data.modelID, parentGo.transform); } } parentGo.transform.eulerAngles = Vector3.zero; childGo.transform.eulerAngles = Vector3.zero; if (previewGo) { data.isLight = true; } BoxCollider parentCollider = parentGo.AddComponent <BoxCollider>(); BoxCollider childCollider; //Expanding collider a little gives better hit detection. float buffer = 0.02f; // Some custom models have a box collider and are made of multiple smaller models. Get the parent collider size. if (childCollider = childGo.GetComponent <BoxCollider>()) { parentCollider.size = new Vector3((childCollider.size.x * childGo.transform.localScale.x) + buffer, (childCollider.size.y * childGo.transform.localScale.y) + buffer, (childCollider.size.z * childGo.transform.localScale.z) + buffer); parentCollider.center = new Vector3(childCollider.center.x * childGo.transform.localScale.x, childCollider.center.y * childGo.transform.localScale.y, childCollider.center.z * childGo.transform.localScale.z); // Child colliders screw with EditMode. GameObject.Destroy(childCollider); } else { Bounds childBounds = childGo.GetComponent <MeshFilter>().sharedMesh.bounds; parentCollider.size = new Vector3((childBounds.size.x * childGo.transform.localScale.x) + buffer, (childBounds.size.y * childGo.transform.localScale.y) + buffer, (childBounds.size.z * childGo.transform.localScale.z) + buffer); parentCollider.center = new Vector3(childBounds.center.x * childGo.transform.localScale.x, childBounds.center.y * childGo.transform.localScale.y, childBounds.center.z * childGo.transform.localScale.z); } parentCollider.isTrigger = true; parentGo.AddComponent <PlacedObject>(); SetPlacedObject(data, parentGo); return(parentGo); }