mirror of
https://github.com/Outer-Wilds-New-Horizons/new-horizons.git
synced 2025-12-11 20:15:44 +01:00
Merge pull request #155 from FreezeDriedMangos/feat/vision-torches
vision torches
This commit is contained in:
commit
89169d7560
@ -1,4 +1,4 @@
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Configs;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
@ -153,6 +153,14 @@ namespace NewHorizons.Builder.Props
|
||||
{
|
||||
socket._sector = sector;
|
||||
}
|
||||
|
||||
// Fix vision torch
|
||||
if (component is VisionTorchItem torchItem)
|
||||
{
|
||||
torchItem.enabled = true;
|
||||
torchItem.mindProjectorTrigger.enabled = true;
|
||||
torchItem.mindSlideProjector._mindProjectorImageEffect = GameObject.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Handlers;
|
||||
using NewHorizons.Utility;
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using static NewHorizons.External.Modules.PropModule;
|
||||
using Logger = NewHorizons.Utility.Logger;
|
||||
namespace NewHorizons.Builder.Props
|
||||
{
|
||||
@ -24,6 +25,12 @@ namespace NewHorizons.Builder.Props
|
||||
case PropModule.ProjectionInfo.SlideShowType.SlideReel:
|
||||
MakeSlideReel(go, sector, info, mod);
|
||||
break;
|
||||
case PropModule.ProjectionInfo.SlideShowType.VisionTorchTarget:
|
||||
MakeMindSlidesTarget(go, sector, info, mod);
|
||||
break;
|
||||
case PropModule.ProjectionInfo.SlideShowType.StandingVisionTorch:
|
||||
MakeStandingVisionTorch(go, sector, info, mod);
|
||||
break;
|
||||
default:
|
||||
Logger.LogError($"Invalid projection type {info.type}");
|
||||
break;
|
||||
@ -68,22 +75,52 @@ namespace NewHorizons.Builder.Props
|
||||
// The base game ones only have 15 slides max
|
||||
var textures = new Texture2D[slidesCount >= 15 ? 15 : slidesCount];
|
||||
|
||||
var imageLoader = slideReelObj.AddComponent<AsyncImageLoader>();
|
||||
for (int i = 0; i < slidesCount; i++)
|
||||
{
|
||||
var slide = new Slide();
|
||||
var slideInfo = info.slides[i];
|
||||
|
||||
var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath);
|
||||
slide.textureOverride = ImageUtilities.Invert(texture);
|
||||
|
||||
// Track the first 15 to put on the slide reel object
|
||||
if (i < 15) textures[i] = texture;
|
||||
imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath);
|
||||
|
||||
AddModules(slideInfo, ref slide);
|
||||
|
||||
slideCollection.slides[i] = slide;
|
||||
}
|
||||
|
||||
// this variable just lets us track how many of the first 15 slides have been loaded.
|
||||
// this way as soon as the last one is loaded (due to async loading, this may be
|
||||
// slide 7, or slide 3, or whatever), we can build the slide reel texture. This allows us
|
||||
// to avoid doing a "is every element in the array `textures` not null" check every time a texture finishes loading
|
||||
int displaySlidesLoaded = 0;
|
||||
imageLoader.imageLoadedEvent.AddListener(
|
||||
(Texture2D tex, int index) =>
|
||||
{
|
||||
slideCollection.slides[index].textureOverride = ImageUtilities.Invert(tex);
|
||||
|
||||
// Track the first 15 to put on the slide reel object
|
||||
if (index < 15)
|
||||
{
|
||||
textures[index] = tex;
|
||||
displaySlidesLoaded++; // threading moment
|
||||
}
|
||||
|
||||
if (displaySlidesLoaded >= textures.Length)
|
||||
{
|
||||
// all textures required to build the reel's textures have been loaded
|
||||
var slidesBack = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Back").GetComponent<MeshRenderer>();
|
||||
var slidesFront = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Front").GetComponent<MeshRenderer>();
|
||||
|
||||
// Now put together the textures into a 4x4 thing for the materials
|
||||
var reelTexture = ImageUtilities.MakeReelTexture(textures);
|
||||
slidesBack.material.mainTexture = reelTexture;
|
||||
slidesBack.material.SetTexture(EmissionMap, reelTexture);
|
||||
slidesFront.material.mainTexture = reelTexture;
|
||||
slidesFront.material.SetTexture(EmissionMap, reelTexture);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Else when you put them down you can't pick them back up
|
||||
slideReelObj.GetComponent<OWCollider>()._physicsRemoved = false;
|
||||
|
||||
@ -95,16 +132,6 @@ namespace NewHorizons.Builder.Props
|
||||
OWAssetHandler.LoadObject(slideReelObj);
|
||||
sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(slideReelObj));
|
||||
|
||||
var slidesBack = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Back").GetComponent<MeshRenderer>();
|
||||
var slidesFront = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Front").GetComponent<MeshRenderer>();
|
||||
|
||||
// Now put together the textures into a 4x4 thing for the materials
|
||||
var reelTexture = ImageUtilities.MakeReelTexture(textures);
|
||||
slidesBack.material.mainTexture = reelTexture;
|
||||
slidesBack.material.SetTexture(EmissionMap, reelTexture);
|
||||
slidesFront.material.mainTexture = reelTexture;
|
||||
slidesFront.material.SetTexture(EmissionMap, reelTexture);
|
||||
|
||||
slideReelObj.SetActive(true);
|
||||
}
|
||||
|
||||
@ -137,18 +164,19 @@ namespace NewHorizons.Builder.Props
|
||||
int slidesCount = info.slides.Length;
|
||||
var slideCollection = new SlideCollection(slidesCount);
|
||||
|
||||
var imageLoader = projectorObj.AddComponent<AsyncImageLoader>();
|
||||
for (int i = 0; i < slidesCount; i++)
|
||||
{
|
||||
var slide = new Slide();
|
||||
var slideInfo = info.slides[i];
|
||||
|
||||
var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath);
|
||||
slide.textureOverride = ImageUtilities.Invert(texture);
|
||||
imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath);
|
||||
|
||||
AddModules(slideInfo, ref slide);
|
||||
|
||||
slideCollection.slides[i] = slide;
|
||||
}
|
||||
imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index].textureOverride = ImageUtilities.Invert(tex); });
|
||||
|
||||
slideCollectionContainer.slideCollection = slideCollection;
|
||||
|
||||
@ -163,6 +191,143 @@ namespace NewHorizons.Builder.Props
|
||||
projectorObj.SetActive(true);
|
||||
}
|
||||
|
||||
// Makes a target for a vision torch to scan
|
||||
public static GameObject MakeMindSlidesTarget(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod)
|
||||
{
|
||||
// spawn a trigger for the vision torch
|
||||
var path = "DreamWorld_Body/Sector_DreamWorld/Sector_Underground/Sector_PrisonCell/Ghosts_PrisonCell/GhostNodeMap_PrisonCell_Lower/Prefab_IP_GhostBird_Prisoner/Ghostbird_IP_ANIM/Ghostbird_Skin_01:Ghostbird_Rig_V01:Base/Ghostbird_Skin_01:Ghostbird_Rig_V01:Root/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine01/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine02/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine03/Ghostbird_Skin_01:Ghostbird_Rig_V01:Spine04/Ghostbird_Skin_01:Ghostbird_Rig_V01:Neck01/Ghostbird_Skin_01:Ghostbird_Rig_V01:Neck02/Ghostbird_Skin_01:Ghostbird_Rig_V01:Head/PrisonerHeadDetector";
|
||||
var g = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, Vector3.zero, 2, false);
|
||||
|
||||
if (g == null)
|
||||
{
|
||||
Logger.LogWarning($"Tried to make a vision torch target but couldn't. Do you have the DLC installed?");
|
||||
return null;
|
||||
}
|
||||
|
||||
g.name = "VisionStaffDetector";
|
||||
|
||||
// The number of slides is unlimited, 15 is only for texturing the actual slide reel item. This is not a slide reel item
|
||||
var slides = info.slides;
|
||||
var slidesCount = slides.Length;
|
||||
var slideCollection = new SlideCollection(slidesCount);
|
||||
|
||||
|
||||
var imageLoader = g.AddComponent<AsyncImageLoader>();
|
||||
for (int i = 0; i < slidesCount; i++)
|
||||
{
|
||||
var slide = new Slide();
|
||||
var slideInfo = slides[i];
|
||||
|
||||
imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath);
|
||||
|
||||
AddModules(slideInfo, ref slide);
|
||||
|
||||
slideCollection.slides[i] = slide;
|
||||
}
|
||||
imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index].textureOverride = tex; });
|
||||
|
||||
|
||||
// attatch a component to store all the data for the slides that play when a vision torch scans this target
|
||||
var target = g.AddComponent<VisionTorchTarget>();
|
||||
var slideCollectionContainer = g.AddComponent<SlideCollectionContainer>();
|
||||
slideCollectionContainer.slideCollection = slideCollection;
|
||||
target.slideCollection = g.AddComponent<MindSlideCollection>();
|
||||
target.slideCollection._slideCollectionContainer = slideCollectionContainer;
|
||||
target.slideCollectionContainer = slideCollectionContainer;
|
||||
|
||||
// Idk why but it wants reveals to be comma delimited not a list
|
||||
if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals);
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
public static GameObject MakeStandingVisionTorch(GameObject planetGO, Sector sector, PropModule.ProjectionInfo info, IModBehaviour mod)
|
||||
{
|
||||
//
|
||||
// spawn the torch itself
|
||||
//
|
||||
|
||||
var path = "RingWorld_Body/Sector_RingWorld/Sector_SecretEntrance/Interactibles_SecretEntrance/Experiment_1/VisionTorchApparatus/VisionTorchRoot/Prefab_IP_VisionTorchProjector";
|
||||
var standingTorch = DetailBuilder.MakeDetail(planetGO, sector, path, info.position, info.rotation, 1, false);
|
||||
|
||||
if (standingTorch == null)
|
||||
{
|
||||
Logger.LogWarning($"Tried to make a vision torch target but couldn't. Do you have the DLC installed?");
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// set some required properties on the torch
|
||||
//
|
||||
|
||||
var mindSlideProjector = standingTorch.GetComponent<MindSlideProjector>();
|
||||
mindSlideProjector._mindProjectorImageEffect = GameObject.Find("Player_Body/PlayerCamera").GetComponent<MindProjectorImageEffect>();
|
||||
|
||||
// setup for visually supporting async texture loading
|
||||
mindSlideProjector.enabled = false;
|
||||
var visionBeamEffect = SearchUtilities.FindChild(standingTorch, "VisionBeam");
|
||||
visionBeamEffect.SetActive(false);
|
||||
|
||||
//
|
||||
// set up slides
|
||||
//
|
||||
|
||||
// The number of slides is unlimited, 15 is only for texturing the actual slide reel item. This is not a slide reel item
|
||||
var slides = info.slides;
|
||||
var slidesCount = slides.Length;
|
||||
var slideCollection = new SlideCollection(slidesCount);
|
||||
|
||||
var imageLoader = standingTorch.AddComponent<AsyncImageLoader>();
|
||||
for (int i = 0; i < slidesCount; i++)
|
||||
{
|
||||
var slide = new Slide();
|
||||
var slideInfo = slides[i];
|
||||
|
||||
imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath);
|
||||
|
||||
AddModules(slideInfo, ref slide);
|
||||
|
||||
slideCollection.slides[i] = slide;
|
||||
}
|
||||
|
||||
// this variable just lets us track how many of the slides have been loaded.
|
||||
// this way as soon as the last one is loaded (due to async loading, this may be
|
||||
// slide 7, or slide 3, or whatever), we can enable the vision torch. This allows us
|
||||
// to avoid doing a "is every element in the array `slideCollection.slides` not null" check every time a texture finishes loading
|
||||
int displaySlidesLoaded = 0;
|
||||
imageLoader.imageLoadedEvent.AddListener(
|
||||
(Texture2D tex, int index) =>
|
||||
{
|
||||
slideCollection.slides[index].textureOverride = tex;
|
||||
displaySlidesLoaded++; // threading moment
|
||||
|
||||
if (displaySlidesLoaded >= slides.Length)
|
||||
{
|
||||
mindSlideProjector.enabled = true;
|
||||
visionBeamEffect.SetActive(true);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// set up the containers for the slides
|
||||
var slideCollectionContainer = standingTorch.AddComponent<SlideCollectionContainer>();
|
||||
slideCollectionContainer.slideCollection = slideCollection;
|
||||
var mindSlideCollection = standingTorch.AddComponent<MindSlideCollection>();
|
||||
mindSlideCollection._slideCollectionContainer = slideCollectionContainer;
|
||||
|
||||
// make sure that these slides play when the player wanders into the beam
|
||||
// _slideCollectionItem is actually a reference to a SlideCollectionContainer. Not a slide reel item
|
||||
mindSlideProjector._mindSlideCollection = mindSlideCollection;
|
||||
mindSlideProjector._slideCollectionItem = slideCollectionContainer;
|
||||
mindSlideProjector.SetMindSlideCollection(mindSlideCollection);
|
||||
|
||||
|
||||
// Idk why but it wants reveals to be comma delimited not a list
|
||||
if (info.reveals != null) slideCollectionContainer._shipLogOnComplete = string.Join(",", info.reveals);
|
||||
|
||||
return standingTorch;
|
||||
}
|
||||
|
||||
private static void AddModules(PropModule.SlideInfo slideInfo, ref Slide slide)
|
||||
{
|
||||
var modules = new List<SlideFunctionModule>();
|
||||
@ -211,4 +376,10 @@ namespace NewHorizons.Builder.Props
|
||||
Slide.WriteModules(modules, ref slide._modulesList, ref slide._modulesData, ref slide.lengths);
|
||||
}
|
||||
}
|
||||
|
||||
public class VisionTorchTarget : MonoBehaviour
|
||||
{
|
||||
public MindSlideCollection slideCollection;
|
||||
public SlideCollectionContainer slideCollectionContainer;
|
||||
}
|
||||
}
|
||||
|
||||
12
NewHorizons/External/Modules/PropModule.cs
vendored
12
NewHorizons/External/Modules/PropModule.cs
vendored
@ -1,7 +1,8 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
using NewHorizons.Utility;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
using NewHorizons.Utility;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
@ -488,7 +489,12 @@ namespace NewHorizons.External.Modules
|
||||
{
|
||||
[EnumMember(Value = @"slideReel")] SlideReel = 0,
|
||||
|
||||
[EnumMember(Value = @"autoProjector")] AutoProjector = 1
|
||||
[EnumMember(Value = @"autoProjector")] AutoProjector = 1,
|
||||
|
||||
[EnumMember(Value = @"visionTorchTarget")] VisionTorchTarget = 2,
|
||||
|
||||
[EnumMember(Value = @"standingVisionTorch")] StandingVisionTorch = 3,
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using NewHorizons.Builder.Body;
|
||||
using NewHorizons.Builder.Body;
|
||||
using NewHorizons.External.Modules;
|
||||
using NewHorizons.Utility;
|
||||
using System.Collections.Generic;
|
||||
|
||||
36
NewHorizons/Patches/ToolModeSwapperPatches.cs
Normal file
36
NewHorizons/Patches/ToolModeSwapperPatches.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace NewHorizons.Patches
|
||||
{
|
||||
[HarmonyPatch]
|
||||
public static class ToolModeSwapperPatches
|
||||
{
|
||||
|
||||
// Patches ToolModeSwapper.EquipToolMode(ToolMode mode) to deny swaps if you're holding a vision torch.
|
||||
// This is critical for preventing swapping to the scout launcher (causes memory slides to fail) but it
|
||||
// just doesn't look right when you switch to other stuff (eg the signalscope), so I'm disabling swapping tools entirely
|
||||
|
||||
// the correct way to do this is to patch ToolModeSwapper.Update to be exactly the same as it is now, but change the below line
|
||||
// to include a check for "is holding vision torch", but I'm not copy/pasting an entire function, no sir
|
||||
// if (((_currentToolMode == ToolMode.None || _currentToolMode == ToolMode.Item) && Locator.GetPlayerSuit().IsWearingSuit(includeTrainingSuit: false)) || ((_currentToolMode == ToolMode.None || _currentToolMode == ToolMode.SignalScope) && OWInput.IsInputMode(InputMode.ShipCockpit)))
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ToolModeSwapper), nameof(ToolModeSwapper.EquipToolMode))]
|
||||
public static bool ToolModeSwapper_EquipToolMode(ToolModeSwapper __instance, ToolMode mode)
|
||||
{
|
||||
var isHoldingVisionTorch = __instance.GetItemCarryTool()?.GetHeldItemType() == ItemType.VisionTorch;
|
||||
var swappingToRestrictedTool =
|
||||
mode == ToolMode.Probe ||
|
||||
mode == ToolMode.SignalScope ||
|
||||
mode == ToolMode.Translator;
|
||||
|
||||
if (isHoldingVisionTorch && swappingToRestrictedTool) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
65
NewHorizons/Patches/VisionTorchPatches.cs
Normal file
65
NewHorizons/Patches/VisionTorchPatches.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using HarmonyLib;
|
||||
using NewHorizons.Builder.Props;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NewHorizons.Patches
|
||||
{
|
||||
|
||||
[HarmonyPatch]
|
||||
public static class MindProjectorTriggerPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(MindProjectorTrigger), nameof(MindProjectorTrigger.OnTriggerVolumeEntry))]
|
||||
public static bool MindProjectorTrigger_OnTriggerVolumeEntry(MindProjectorTrigger __instance, GameObject hitObj)
|
||||
{
|
||||
var t = hitObj.GetComponent<VisionTorchTarget>();
|
||||
if (t != null) //(hitObj.CompareTag("PrisonerDetector"))
|
||||
{
|
||||
// _slideCollectionItem is actually a reference to a SlideCollectionContainer. Not a slide reel item
|
||||
__instance._mindProjector._slideCollectionItem = t.slideCollectionContainer;
|
||||
__instance._mindProjector._mindSlideCollection = t.slideCollection;
|
||||
__instance._mindProjector.SetMindSlideCollection(t.slideCollection);
|
||||
|
||||
__instance.OnBeamStartHitPrisoner.Invoke();
|
||||
__instance._mindProjector.Play(reset: true);
|
||||
__instance._mindProjector.OnProjectionStart += new OWEvent.OWCallback(__instance.OnProjectionStart);
|
||||
__instance._mindProjector.OnProjectionComplete += new OWEvent.OWCallback(__instance.OnProjectionComplete);
|
||||
|
||||
Locator.GetPlayerTransform().GetComponent<PlayerLockOnTargeting>().LockOn(hitObj.transform, Vector3.zero);
|
||||
__instance._playerLockedOn = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch]
|
||||
public static class VisionTorchItemPatches
|
||||
{
|
||||
// This is some dark magic
|
||||
// this creates a method called base_DropItem that basically just calls OWItem.PickUpItem whenever it (VisionTorchItemPatches.base_PickUpItem) is called
|
||||
[HarmonyReversePatch]
|
||||
[HarmonyPatch(typeof(OWItem), nameof(OWItem.DropItem))]
|
||||
private static void base_DropItem(OWItem instance, Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget) { }
|
||||
|
||||
|
||||
// Make the vision torch droppable. In the base game you can only drop it if you're in the dream world.
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(VisionTorchItem), nameof(VisionTorchItem.DropItem))]
|
||||
public static bool VisionTorchItem_DropItem(VisionTorchItem __instance, Vector3 position, Vector3 normal, Transform parent, Sector sector, IItemDropTarget customDropTarget)
|
||||
{
|
||||
if (!Locator.GetDreamWorldController().IsInDream())
|
||||
{
|
||||
base_DropItem(__instance, position, normal, parent, sector, customDropTarget);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,12 @@
|
||||
using OWML.Common;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace NewHorizons.Utility
|
||||
{
|
||||
public static class ImageUtilities
|
||||
@ -314,4 +318,46 @@ namespace NewHorizons.Utility
|
||||
return newTexture;
|
||||
}
|
||||
}
|
||||
|
||||
// Modified from https://stackoverflow.com/a/69141085/9643841
|
||||
public class AsyncImageLoader : MonoBehaviour
|
||||
{
|
||||
public List<string> pathsToLoad = new List<string>();
|
||||
|
||||
public class ImageLoadedEvent : UnityEvent<Texture2D, int> { }
|
||||
public ImageLoadedEvent imageLoadedEvent = new ImageLoadedEvent();
|
||||
|
||||
// TODO: set up an optional “StartLoading” and “StartUnloading” condition on AsyncTextureLoader,
|
||||
// and make use of that for at least for projector stuff (require player to be in the same sector as the slides
|
||||
// for them to start loading, and unload when the player leaves)
|
||||
|
||||
void Start()
|
||||
{
|
||||
for (int i = 0; i < pathsToLoad.Count; i++)
|
||||
{
|
||||
StartCoroutine(DownloadTexture(pathsToLoad[i], i));
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator DownloadTexture(string url, int index)
|
||||
{
|
||||
using (UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url))
|
||||
{
|
||||
yield return uwr.SendWebRequest();
|
||||
|
||||
var hasError = uwr.error != null && uwr.error != "";
|
||||
|
||||
if (hasError) // (uwr.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
Debug.Log(uwr.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get downloaded asset bundle
|
||||
var texture = DownloadHandlerTexture.GetContent(uwr);
|
||||
imageLoadedEvent.Invoke(texture, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
@ -119,6 +119,16 @@ namespace NewHorizons.Utility
|
||||
}
|
||||
*/
|
||||
|
||||
public static GameObject FindChild(GameObject g, string childName)
|
||||
{
|
||||
foreach(Transform child in g.transform)
|
||||
{
|
||||
if (child.gameObject.name == childName) return child.gameObject;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static GameObject Find(string path)
|
||||
{
|
||||
if (CachedGameObjects.ContainsKey(path))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user