/// <summary> /// Seek and import a GameObject from mods to replace a Daggerfall billboard. /// </summary> /// <param name="archive">Texture archive for original billboard.</param> /// <param name="record">Texture record for original billboard.</param> /// <param name="position">Position to assign to GameObject.</param> /// <param name="parent">Parent to assign to GameObject.</param> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null if not found.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { GameObject go; if (!TryImportGameObject(archive, record, true, out go)) { return(null); } go.name = GetFlatReplacementName(archive, record); go.transform.parent = parent; // Assign position AlignToBase(go.transform, position, archive, record, inDungeon); // Assign a random rotation var iObjectPositioner = go.GetComponent <IObjectPositioner>(); if (iObjectPositioner == null || iObjectPositioner.AllowFlatRotation) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
/// <summary> /// Seek and import a GameObject from mods to replace a Daggerfall billboard. /// </summary> /// <param name="archive">Texture archive for original billboard.</param> /// <param name="record">Texture record for original billboard.</param> /// <param name="position">Position to assign to GameObject.</param> /// <param name="parent">Parent to assign to GameObject.</param> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null if not found.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { GameObject go; if (!TryImportGameObject(archive, record, true, out go)) { return(null); } go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); go.transform.parent = parent; // Assign position AlignToBase(go.transform, position, archive, record, inDungeon); // Assign a random rotation if (go.GetComponent <FaceWall>() == null) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
/// <summary> /// Import a GameObject from mods instead of billboard. /// </summary> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { // Check user settings if (!DaggerfallUnity.Settings.MeshAndTextureReplacement) { return(null); } // Get GameObject GameObject prefab; string name = archive.ToString("D3") + "_" + record.ToString(); if (!LoadGameObjectFromMods("Flats", name, out prefab)) { return(null); } // Instantiate GameObject GameObject go = GameObject.Instantiate(prefab, parent); go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); // Assign position if (inDungeon) { // Fix origin position for dungeon flats int height = ImageReader.GetImageData("TEXTURE." + archive.ToString("D3"), record, createTexture: false).height; position.y -= height / 2 * MeshReader.GlobalScale; } go.transform.localPosition = position; // Assign a random rotation if (go.GetComponent <FaceWall>() == null) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
/// <summary> /// Seek and import a GameObject from mods to replace a Daggerfall billboard. /// </summary> /// <param name="archive">Texture archive for original billboard.</param> /// <param name="record">Texture record for original billboard.</param> /// <param name="position">Position to assign to GameObject.</param> /// <param name="parent">Parent to assign to GameObject.</param> /// <param name="inDungeon">Fix position for dungeon models.</param> /// <returns>Returns the imported model or null if not found.</returns> public static GameObject ImportCustomFlatGameobject(int archive, int record, Vector3 position, Transform parent, bool inDungeon = false) { GameObject go; if (!TryImportGameObject(archive, record, true, out go)) { return(null); } go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); go.transform.parent = parent; // Assign position if (inDungeon) { // Fix origin position for dungeon flats int height = ImageReader.GetImageData(TextureFile.IndexToFileName(archive), record, createTexture: false).height; position.y -= height / 2 * MeshReader.GlobalScale; } go.transform.localPosition = position; // Assign a random rotation if (go.GetComponent <FaceWall>() == null) { Random.InitState((int)position.x); go.transform.Rotate(0, Random.Range(0f, 360f), 0); } // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } // Finalise gameobject materials FinaliseMaterials(go); return(go); }
/// <summary> /// Assign parent, position, rotation and texture filtermode. /// </summary> static private void InstantiateCustomFlat(GameObject go, ref Vector3 position, Transform parent, int archive, int record, bool inDungeon) { // Fix origin position for dungeon flats if (inDungeon) { // Get height int height = ImageReader.GetImageData("TEXTURE." + archive.ToString("D3"), record, createTexture: false).height; // Correct transform position.y -= height / 2 * MeshReader.GlobalScale; } // Assign transform properties go.transform.parent = parent; go.transform.localPosition = position; // Assign a random rotation so that flats in group won't look all aligned. // We use a seed becuse we want the models to have the same // rotation every time the same location is loaded. if (go.GetComponent <FaceWall>() == null) { UnityEngine.Random.InitState((int)position.x); go.transform.Rotate(0, UnityEngine.Random.Range(0f, 360f), 0); } // Assign name go.name = string.Format("DaggerfallBillboard [Replacement] [TEXTURE.{0:000}, Index={1}]", archive, record); // Finalise gameobject material FinaliseMaterials(go); // Add NPC trigger collider if (RDBLayout.IsNPCFlat(archive)) { Collider col = go.AddComponent <BoxCollider>(); col.isTrigger = true; } }
/// <summary> /// Sets new Daggerfall material and recreates mesh. /// Will use an atlas if specified in DaggerfallUnity singleton. /// </summary> /// <param name="dfUnity">DaggerfallUnity singleton. Required for content readers and settings.</param> /// <param name="archive">Texture archive index.</param> /// <param name="record">Texture record index.</param> /// <param name="frame">Frame index.</param> /// <returns>Material.</returns> public Material SetMaterial(int archive, int record, int frame = 0) { // Get DaggerfallUnity DaggerfallUnity dfUnity = DaggerfallUnity.Instance; if (!dfUnity.IsReady) { return(null); } // Get references meshRenderer = GetComponent <MeshRenderer>(); Vector2 size; Vector2 scale; Mesh mesh = null; Material material = null; if (material = TextureReplacement.GetStaticBillboardMaterial(gameObject, archive, record, ref summary, out scale)) { mesh = dfUnity.MeshReader.GetBillboardMesh(summary.Rect, archive, record, out size); size *= scale; summary.AtlasedMaterial = false; summary.AnimatedMaterial = summary.ImportedTextures.FrameCount > 1; } else if (dfUnity.MaterialReader.AtlasTextures) { material = dfUnity.MaterialReader.GetMaterialAtlas( archive, 0, 4, 2048, out summary.AtlasRects, out summary.AtlasIndices, 4, true, 0, false, true); mesh = dfUnity.MeshReader.GetBillboardMesh( summary.AtlasRects[summary.AtlasIndices[record].startIndex], archive, record, out size); summary.AtlasedMaterial = true; if (summary.AtlasIndices[record].frameCount > 1) { summary.AnimatedMaterial = true; } else { summary.AnimatedMaterial = false; } } else { material = dfUnity.MaterialReader.GetMaterial( archive, record, frame, 0, out summary.Rect, 4, true, true); mesh = dfUnity.MeshReader.GetBillboardMesh( summary.Rect, archive, record, out size); summary.AtlasedMaterial = false; summary.AnimatedMaterial = false; } // Set summary summary.FlatType = MaterialReader.GetFlatType(archive); summary.Archive = archive; summary.Record = record; summary.Size = size; // Set editor flat types if (summary.FlatType == FlatTypes.Editor) { summary.EditorFlatType = MaterialReader.GetEditorFlatType(summary.Record); } // Set NPC flat type based on archive if (RDBLayout.IsNPCFlat(summary.Archive)) { summary.FlatType = FlatTypes.NPC; } // Assign mesh and material MeshFilter meshFilter = GetComponent <MeshFilter>(); Mesh oldMesh = meshFilter.sharedMesh; if (mesh) { meshFilter.sharedMesh = mesh; meshRenderer.sharedMaterial = material; } if (oldMesh) { // The old mesh is no longer required #if UNITY_EDITOR DestroyImmediate(oldMesh); #else Destroy(oldMesh); #endif } // General billboard shadows if enabled bool isLightArchive = (archive == TextureReader.LightsTextureArchive); meshRenderer.shadowCastingMode = (DaggerfallUnity.Settings.GeneralBillboardShadows && !isLightArchive) ? ShadowCastingMode.TwoSided : ShadowCastingMode.Off; // Add NPC trigger collider if (summary.FlatType == FlatTypes.NPC) { Collider col = gameObject.AddComponent <BoxCollider>(); col.isTrigger = true; } return(material); }