# Unity 筆記 *崩潰歷程* :::danger **適用2019版本的unity** ::: ## :arrow_forward:[確認物件是否被啟動] >```c++= >if物件.activeInHierarchy == false >``` ## :arrow_forward:[確認Bool] >```c++= >if (shopOpened) >{ > shopOpened = false; >} > ``` ## :arrow_forward:[抓取文字框裡的文字] >```c++= >public Text storydia; >//public GameObject storydialog; > //storydia=storydialog.GetComponent<Text>(); >storydialog.text=="呃.....頭好痛,該死的喝太多了" >``` ## :arrow_forward:[抓取float] >```c++= >ObjectShake sha; >public Image bloodgauge; >sha=Canvasbg.GetComponent<ObjectShake>(); > bloodgauge.fillAmount = 0f; > if(bloodgauge.fillAmount>=1f) >``` ## :arrow_forward:[抓取物件裡namepace的腳本] > 出處 https://answers.unity.com/questions/1010118/how-to-use-getcomponent-with-a-namespace.html >```c++= > using MyNamespace; ## :arrow_forward:[抓取物件裡的腳本] > 出處 https://forum.unity.com/threads/how-can-i-reference-to-a-component-of-another-gameobject.280451/ > 跟 https://gamedev-stackexchange-com.translate.goog/questions/134022/how-to-disable-script-component-while-in-game?_x_tr_sl=en&_x_tr_tl=zh-TW&_x_tr_hl=zh-TW&_x_tr_pto=sc >```c++= >public GameObject Canvasbg; > 腳本名字 sha; > sha=Canvasbg.GetComponent<ObjectShake>(); > sha.enabled = false; ## :arrow_forward:[抓取UI開關] >```c++= > private Image tvimg; > public GameObject tv; > tvimg = tv.GetComponent<Image>(); >image.enabled = true; >image.enabled = false; >``` ## :arrow_forward:[抓取PostProcess] >出處 https://forum.unity.com/threads/how-to-modify-post-processing-profiles-in-script.758375/ > 跟 https://forum.unity.com/threads/urp-volume-cs-how-to-access-the-override-settings-at-runtime-via-script.813093/#post-5415663 >```c++= > using UnityEngine.Rendering.PostProcessing; > public PostProcessVolume volume; > volume = cam[0].GetComponent<PostProcessVolume>(); ## :arrow_forward:[抓取/控制動畫播放] >```c++= > public Animator anim; > // Start is called before the first frame update > void Start() > { > anim=GetComponent<Animator>();//抓住動畫 > } > > // Update is called once per frame > void Update() > { > if (Input.GetKey(KeyCode.Space)) > { > anim.SetBool("fly",true);//bool > } > else if(Input.GetKeyUp(KeyCode.Space)) > { > anim.SetBool("fly",false); > } > } //if (amim.GetBool("Sword")) 確認動畫撥放 >``` >![](https://i.imgur.com/Jk37kyl.png) ## :arrow_forward:[抓取場景物件] >```c++= > // 在 room 場景中找到名為 "flow" 的物件 >GameObject flow = GameObject.Find("flow"); > if (flow != null) > { > // 在 "flow" 物件下找到名為 "saydia" 的物件 > saydia = flow.transform.Find("saydia").gameObject; > if (!isDialogShown && saydia != null) > { > saydia.SetActive(true); > } > } >``` ## :arrow_forward:[如果滑鼠Hover過去/離開] >```c++= >public class 啥啥啥 : MonoBehaviour, IPointerExitHandler, IPointerEnterHandler >using UnityEngine.UI; >using UnityEngine.EventSystems; >public void OnPointerEnter(PointerEventData eventData) > public void OnPointerExit(PointerEventData eventData) >``` ## :arrow_forward:[如果滑鼠Hover過去按下Button] >```c++= > using UnityEngine.UI; > using UnityEngine.EventSystems; > public class spaceclickhover : MonoBehaviour, IPointerEnterHandler > { > public Button button; > public bool hovered; > private void Start() > { > // 获取Button组件 > button = GetComponent<Button>(); > > // 将OnClick事件指定为空函数 > button.onClick.AddListener(() => { }); > // ishover=image.GetComponent<Image>(); > } > public void OnPointerEnter(PointerEventData eventData) > { > hovered = true; > // 如果正在悬停在此对象上且按下了空格键,则触发OnClick> 事件 > } > void Update() > { > if (hovered==true&&Input.GetKeyDown(KeyCode.Space)) > { > button.onClick.Invoke(); > } > } > public void OnPointerExit(PointerEventData eventData) > { > hovered = false; > Debug.Log("Stopped Hovering"); > } > } ## :arrow_forward:[選取所有子物件,更換材質] >```c++= > public Material [] newMaterials; > private Renderer [] rends; > void Start() > { > rends = GetComponentsInChildren<Renderer>(); > > if (rends == null || rends.Length == 0) > { > Debug.LogError("Renderer component not found on the object."); > return; > } > foreach(Renderer rend in rends) > { > rend.shareMaterials=newMaterials; > } > } > public void ChangeMaterial() > { > foreach(Renderer rend in rends) > { > rend.shareMaterials=newMaterials; > } > } ## :arrow_forward:[建立清單,對清單裡的東西做同一件事] >```c++= > public GameObject[] arrow; > public void say() > { foreach (GameObject objeto in arrow) > { > objeto.SetActive(false); > } > } ## :arrow_forward:[確認物件清單內都沒啟動] >```c++= >public List<GameObject> myList; > int currentActiveIndex = 0; > void Update() > { > if( myList[currentActiveIndex].activeInHierarchy==false) > } ## :arrow_forward:[音樂淡出入] > https://www.zoearthmoon.net/blog/program/item/3125.html >```c++= >using System.Collections; >using System.Collections.Generic; >using UnityEngine; > > public class fademusic : MonoBehaviour > > { private AudioSource soundtrackAudioSource; > public float fadeTime; > private bool play; > private float originalVolume; // 原始音量值 > > void Start() > { > soundtrackAudioSource = GetComponent<AudioSource>(); > originalVolume = soundtrackAudioSource.volume; // 儲存原始音量值 > soundtrackAudioSource.volume = 0f; // 將音量設置為0 > } > > void Update() > { > if (!play) > { > StartCoroutine(FadeIn()); > play = true; > } > } > > public void StartFadeIn() > { > StartCoroutine(FadeIn()); > } > > public void StartFadeOut() > { > StartCoroutine(FadeOut()); > } > > private IEnumerator FadeIn() > { > float targetVolume = originalVolume; // 目標音量為原始音量值 > > while (soundtrackAudioSource.volume < targetVolume) > { > soundtrackAudioSource.volume += Time.deltaTime / fadeTime; > yield return null; > } > > soundtrackAudioSource.volume = targetVolume; // 確保音量> 最終達到原始數值 > } > > private IEnumerator FadeOut() > { > float targetVolume = 0f; // 目標音量為0 > > while (soundtrackAudioSource.volume > targetVolume) > { > soundtrackAudioSource.volume -= Time.deltaTime / >fadeTime; > yield return null; > } > > soundtrackAudioSource.volume = targetVolume; // 確保音量> 最終達到0 > } > } ## :arrow_forward:[切換場景音樂繼續] > 出處 https://answers.unity.com/questions/1260393/make-music-continue-playing-through-scenes.html > https://www.youtube.com/watch?v=ha6U8jHl9ak&t=105s >```c++= >//連結tag為music的物件 > private AudioSource _audioSource; > DontDestroyOnLoad(transform.gameObject); > _audioSource = GetComponent<AudioSource>(); > public void PlayMusic() > { > if (_audioSource.isPlaying) return; > _audioSource.Play(); > } > public void StopMusic() > { > _audioSource.Stop(); > } > //想播放就 GameObject.FindGameObjectWithTag("Music").GetComponent<MusicClass>().PlayMusic(); >```c++= > public static musiccon instance; > void Awake() > { > if (instance != null) > Destroy(gameObject); > else > { > instance = this; > DontDestroyOnLoad(this.gameObject); > } > } > ## :arrow_forward:[按空白鍵撥放,影片重複播放時停止] > 出處 https://forum.unity.com/threads/how-to-know-video-player-is-finished-playing-video.483935/ > 或是這個 > https://stackoverflow.com/questions/44696030/detect-when-videoplayer-has-finished-playing > 或是這個 https://www.ame-name.com/archives/2665 >```c++= > using System.Collections; > using System.Collections.Generic; > using UnityEngine; > using UnityEngine.UI; > using UnityEngine.Video; > public class PlayMoviebleed : MonoBehaviour > { > > public VideoPlayer videoPlayer; > void Start() > { > videoPlayer.GetComponent<VideoPlayer>(); > videoPlayer.loopPointReached +=CheckOver; > > } > > // Update is called once per frame > void Update() > { > if (Input.GetKeyDown(KeyCode.Space)) > { > PlayVideo(); > > } > } > void CheckOver(UnityEngine.Video.VideoPlayer videoPlayer) > { > print ("Video Is Over"); > videoPlayer.Stop(); > > } > public void PlayVideo() > { > videoPlayer.Play(); > } > } ## :arrow_forward:[暫停世界] >```c++= > public AudioSource audioSource; > public static bool gameIsPaused; > void Update() > { > if (Input.GetKeyDown(KeyCode.Escape)) > { > gameIsPaused = !gameIsPaused; > PauseGame(); > } > } > void PauseGame () > { > if(gameIsPaused) > { > Time.timeScale = 0f; > audioSource.Stop(); > print("puase"); > } > else > { > Time.timeScale = 1; > audioSource.Play(); > } > } ## :arrow_forward:[創建物件清單] >```c++= > [SerializeField] > public GameObject[] cam = new GameObject[4]; > cam[0].SetActive(true); ## :arrow_forward:[隱藏滑鼠] >```c++= > Cursor.visible = false; ## :arrow_forward:[按鈕被按] >```c++= > using UnityEngine.UI; > public Button cafebtimg; > void Start() > { > Button btn1 = cafebtimg.GetComponent<Button>(); > > } > void Update() > { > cafebtimg.onClick.AddListener(closechoseimg); > } > public void closechoseimg() > { > chosecanvas.SetActive(false); > } ## :arrow_forward:[按鈕實行Onclick] >```c++= > private Button button; > private void Start() > { > // 获取Button组件 > button = GetComponent<Button>(); > // 将OnClick事件指定为空函数 > button.onClick.AddListener(() => { }); > // ishover=image.GetComponent<Image>(); > } > if (Input.GetKeyDown(KeyCode.Space)//按下了空格键,则触发OnClick事件 > { > button.onClick.Invoke(); > } ## :arrow_forward:[滑鼠點擊物件] >```c++= >using System.Collections; >using System.Collections.Generic; >using UnityEngine; >using UnityEngine.SceneManagement; >public class SceneOneScript: MonoBehaviour { >// Start is called before the first frame update >void Start() {} >// Update is called once per frame >void Update() >{ > if (Input.GetMouseButtonDown(0)) >{ > Ray ray = >Camera.main.ScreenPointToRay(Input.mousePosition); > RaycastHit hit; > if (Physics.Raycast(ray, out hit)) > { >//Select stage > if (hit.transform.name == "Cube") > { > SceneManager.LoadScene("SceneTwo"); > } > } > } >} >} >``` ## :arrow_forward:[點擊物件快速旋轉,隨著時間推移降速] >> 來源: >> https://stackoverflow.com/questions/69726955/how-to-slow-a-rotating-object-in-unity >```c++= >public class Rotater : MonoBehaviour >{ >public float spinDuration = 3f; >public float targetSpin = 3600f; >float initSpin = 0f; >float initSpeed = 0f; >float acceleration = 0f; >float startRotTime = 0f; >private void CalcInitSpeedingConditions() >{ >// Here we assume constant acceleration, and ending speed >must be 0. >initSpeed = 2 * targetSpin / spinDuration; >acceleration = -initSpeed / spinDuration; >} >void Update() >{ >if (Input.GetKeyDown(KeyCode.Space)) >{ >// targetSpin = Random.Range(1000f, 1360f); # Use this to >spin random on each press >CalcInitSpeedingConditions(); >startRotTime = Time.time; >initSpin = transform.localEulerAngles.y; >StartCoroutine(Rotate()); >} >} >// This is fundamental physics formula >private float GetRotationByTime(float t) => initSpeed * t >+ acceleration * t * t / 2; >IEnumerator Rotate() >{ >float t = Time.time - startRotTime; >while (t < spinDuration) >{ >t = Time.time - startRotTime; >GetRotationByTime(t); >transform.localEulerAngles = Vector3.up * (initSpin + >GetRotationByTime(t) % 360); >yield return null; >} >transform.localEulerAngles = Vector3.up * (initSpin + >GetRotationByTime(t) % 360); >} >} >``` >>3D的語法可能是up,2D用forward![](https://i.imgur.com/PvU8TTA.png) ## :arrow_forward:[名牌系統:顯示物件名稱/內容,掛在物件上] ### 掛要顯示物件身上,要加碰撞 來源:https://youtu.be/uUXmbYVFWME >>![](https://i.imgur.com/hoYvJjU.png) >```c++= >using System.Collections; >using System.Collections.Generic; >using UnityEngine; >using UnityEngine.UI; >public class ObjectController : MonoBehaviour >{ >[SerializeField]private string itemName; >[TextArea][SerializeField]private string itemExtraInfo; >[SerializeField]private Inspectcontroller inspectcontroller; >public void ShowObjectName() >{ >inspectcontroller.ShowName(itemName); >} >public void HideObjectName() >{ >i>nspectcontroller.HideName(); >} >public void ShowExtraInfo() >{ >inspectcontroller.ShowAdditionalInfo(itemExtraInfo); >} >} >``` ### 掛要顯示物件身上,要加碰撞 >>![](https://i.imgur.com/XKbEl9C.png) >```c++= >using System.Collections; >using System.Collections.Generic; >using UnityEngine; >using UnityEngine.UI; >public class inspectray : MonoBehaviour >{ >[SerializeField] private int rayLengh=5; >[SerializeField] private LayerMask layerMaskInteract; >private ObjectController raycastedObj; >// public GameObject hitobject; >//[SerializeField] private Image crosshair; >private bool isCrosshairActive; >private bool doOnce; >private void Update() >{ >RaycastHit hit; >Vector3 fwd = >transform.TransformDirection(Vector3.forward); >if(Physics.Raycast(transform.position, fwd, out hit, >rayLengh, layerMaskInteract.value)) >{ >if(hit.collider.CompareTag("InteractObject")) >{ >if(!doOnce) >{ >raycastedObj=hit.collider.gameObject.GetComponent<ObjectCon>troller>(); >raycastedObj.ShowObjectName(); >// hit.transform.SendMessage("HitByRay"); >// CrosshirChange(true); >} >isCrosshairActive=true; >doOnce=true; >if(Input.GetMouseButtonDown(0)) >{ >raycastedObj.ShowExtraInfo(); >Debug.Log("Transform Tag is:coll " + gameObject.tag); >} >} >} >else{ >if(isCrosshairActive) >{ >// hitobject.SendMessage( "HitExit" ); >raycastedObj.HideObjectName(); >// CrosshirChange(false); >doOnce=false; >} >} >} > >``` ### 顯示文字的UI/canvas >> ![](https://i.imgur.com/XUNi803.png) ### 掛在空物件上控制顯示UI >>![](https://i.imgur.com/8t9UNnt.png) >```c++= >using System.Collections; >using System.Collections.Generic; >using UnityEngine; >using UnityEngine.UI; >public class Inspectcontroller : MonoBehaviour >{ >[SerializeField]private GameObject objectnameBG; >[SerializeField]private Text objectNameUI; >// [SerializeField]private float onScreenTimer; >[SerializeField]private Text extraInfoUI; >[SerializeField]private GameObject extraInfoBG; >// [HideInInspector]public bool statTimer; >// private float timer; >private void Start() >{ >objectnameBG.SetActive(false); >extraInfoBG.SetActive(false); >} >private void Update() >{ >ClearAdditionalInfo(); >/* if(statTimer) >{ > timer-=Time.deltaTime; >if(timer<=0) >{ >timer=0; >ClearAdditionalInfo(); >statTimer=false; >} >}*/ >} >public void ShowName(string objectName) >{ >objectnameBG.SetActive(true); >objectNameUI.text=objectName; >} >public void HideName() >{ >objectnameBG.SetActive(false); >objectNameUI.text=""; >} >public void ShowAdditionalInfo(string newInfo) >{ >// timer=onScreenTimer; >// statTimer=true; >extraInfoBG.SetActive(true); >extraInfoUI.text=newInfo; >} >void ClearAdditionalInfo() >{ >if(extraInfoBG.activeSelf && Input.GetMouseButtonDown(0)) >{ >extraInfoBG.SetActive(false); >extraInfoUI.text=""; >} >} >// Start is called before the first frame update >} ## :arrow_forward:[開關Animator] >```c++= > Imagefade.GetComponent<Animator>().enabled = false; ## :arrow_forward:[Waitforsec] > 出處 http://fanshengye.blogspot.com/2015/10/unity1-waitforseconds.html >跟 https://answers.unity.com/questions/301868/yield-waitforseconds-outside-of-timescale.html >```c++= > void Start() > { > StartCoroutine(Example()); > } > IEnumerator Example() > { > print(Time.time); > yield return new WaitForSeconds(5); > print(Time.time); > } ## :arrow_forward:[繼承上一個場景的數值要static] >![](https://i.imgur.com/HEscyGC.png) >然後抓住那個腳本名稱 >>![](https://i.imgur.com/SMK0UMS.png) ## :arrow_forward:[事件只發生一次在update()] >出處 https://answers.unity.com/questions/746147/make-something-happen-just-once-in-update.html >```c++= > bool heliSpawned; > void Update() > { > if(kills == 15) > { > if(!heliSpawned) > > { > Instantiate(heli, transform.position, transform.rotation); > heliSpawned = true; > } > > } > } ## :arrow_forward:[確認場景] > 出處 https://stackoverflow.com/questions/40043555/unity-check-if-scene-gamescene 跟 > https://answers.unity.com/questions/1173303/how-to-check-which-scene-is-loaded-and-write-if-co.html >```c++= > using UnityEngine.SceneManagement; > if (SceneManager.GetActiveScene().name == "gamescene") { } ## :arrow_forward:[載入場景] >```c++= > using UnityEngine.SceneManagement; > UnityEngine.SceneManagement.SceneManager.LoadScene("really sad 2",LoadSceneMode.Single); ## :arrow_forward:[音樂播放] > 出處 https://stackoverflow.com/questions/49451295/audio-not-playing-in-unity >```c++= > public AudioSource soundSource; > if (!soundSource.isPlaying) > { > soundSource.Play(); > { > ## :arrow_forward:[音樂停止/接收者聽不到] > 出處 https://stackoverflow.com/questions/54348225/stop-all-audiosources-in-every-scene-in-unity >```c++= > public void MuteAllSound() > { > AudioListener.volume = 0; > } > public void UnMuteAllSound() > { > AudioListener.volume = 1; > } > ## :arrow_forward:[切換下一個物件(切鏡頭)] >出處 https://blog.csdn.net/weixin_42893944/article/details/113790720 >```c++= > public class camswitch : MonoBehaviour >{ > public GameObject[] cam; > public bool change=true; > float gaugeAmount; > public Image bloodgauge; > // Start is called before the first frame update > void Start() > { > cam[0].SetActive(true); > cam[1].SetActive(false); > cam[2].SetActive(false); > cam[3].SetActive(false); > > } > public int i=0; > // Update is called once per frame > void Update() > { > if(Input.GetKey(X)) > { > i=i+1; > i=i%4; > switchcam(i); > } > > } > void switchcam(int index) > { > int k=0; > for(k=0;k<cam.Length;k++) > { > if(k==index) > { > cam[k].SetActive(true); > } > if(k!=index) > { > cam[k].SetActive(false); > } > } > > } > >} ## :arrow_forward:[隨著時間切鏡頭] >出處 https://home.gamer.com.tw/creationDetail.php?sn=4401202 >```c++= > public GameObject[] cam; > public bool change=true; > float gaugeAmount; > public Image bloodgauge; > // Start is called before the first frame update > void Start() > { > cam[0].SetActive(true); > cam[1].SetActive(false); > cam[2].SetActive(false); > cam[3].SetActive(false); > } > public int i=0; > void Update() > { > if(bloodgauge.fillAmount>=1f) > { > Invoke(nameof(opencam1),2); > if(cam[1].activeInHierarchy==true) > { > Invoke(nameof(opencam2),2); > } > if(cam[2].activeInHierarchy==true) > { > Invoke(nameof(opencam3),2); > } > } > > } > void switchcam(int index) > { > int k=0; > for(k=0;k<cam.Length;k++) > { > if(k==index) > { > cam[k].SetActive(true); > } > if(k!=index) > { > cam[k].SetActive(false); > } > } > > } > > void opencam1() > { > switchcam(1); > } > void opencam2() > { > switchcam(2); > } > void opencam3() > { > switchcam(3); > } # Unity 資源庫 ::: danger ## 一些別人寫好的工具 ::: ## [生命值] > https://youtu.be/vQyQGZuqDtg?si=UhHIC1Oip9cLop50 >```c++= > using UnityEngine; >using UnityEngine.UI; > public class UIfill : MonoBehaviour >{ > public int maxValue; > public Image fill; > private int currentValue; > > void Start() > { > currentValue=maxValue; > fill.fillAmount=1; > } > void Update() > { > if(Input.GetKeyDown(KeyCode.A)) > Deduct(10); > } > public void Add(int i) > { > currentValue+=i; > if(currentValue>maxValue) > currentValue=maxValue; > fill.fillAmount=(float)currentValue/maxValue; > } > public void Deduct(int i) > { > currentValue-=i; > if(currentValue<0) > currentValue=0; > fill.fillAmount=(float)currentValue/maxValue; > } >} ## 發光UI > https://www.youtube.com/watch?v=hiRdux33UCs > https://github.com/Elringus/SpriteGlow ## 各種特殊材質球 > https://baba-s.hatenablog.com/entry/2018/04/17/085900 > https://github.com/andydbc/unity-shadergraph-sandbox ## UI特效 > https://github.com/mob-sakai/UIEffect ## Unity輸入去背影片 > https://medium.com/@pofu.lu/unity-transparent-video-%E7%94%A8-videoplayer-%E6%88%96-avpro-%E6%92%AD%E6%94%BE%E9%80%8F%E6%98%8E%E5%BD%B1%E7%89%87-83b4b6b4aefd ## 物件搖晃 > https://gist.github.com/GuilleUCM/d882e228d93c7f7d0820 ## 噴濺/潑灑/畫畫系統 > https://dmayance.com/unity-paint-part-2/ ## 肉塊噴濺? > https://forum.unity.com/threads/wip-ultimate-gore-system.528812/ ## 切割物體 > https://www.jianshu.com/p/aa77513ad370 > https://www.youtube.com/watch?v=xgoUmrhXyYE ## 毀滅戰士2噴血 > https://www.moddb.com/games/doom-ii/addons/half-life-beta-blood-decal-for-gzdoom ## 攝影機縮放 > https://twitter.com/chakapo/status/1598987193128656896?s=20&t=6F00wJK6FdYUQVAeUv-1Hg > ![](https://i.imgur.com/mRF8HeD.png) ## 暫停選單 > https://thestraightuptech.itch.io/simple-pause-menu-in-unity # Unity 小除錯 出什麼問題就看這邊 ## :no_entry:[atUnityEditor.BuildPlayerWindow+DefaultBuildMethods.BuildPlayer] >輸出遊戲在桌面(換位置)可以修好 ## :no_entry:[PostProcessing does not exist ] > ### 出處 ## :no_entry:[Legacy AnimationClips are not allowed in Animator Controllers ] > ### 出處 https://answers.unity.com/questions/1200941/help-please-legacy-animationclips-are-not-allowed.html 1.Look at the Animation Clip in the inspector. 2.Click the three-bar dropdown next to the lock icon in the top right. 3.Select debug. 4.Uncheck legacy. ## :no_entry:[CS0019: Operator '&&' cannot be applied to operands of type 'string' and 'bool'] >![](https://i.imgur.com/tunzVlq.png) ## :warning:[看不到UI canvas處理:兩台攝影機] >![](https://i.imgur.com/fXRrmbE.png) layer要加 ![](https://i.imgur.com/U0seHUq.png) 用來專看特效的攝影機![](https://i.imgur.com/2vefzVq.png) ## :warning:[Button沒有反應時要確認] * 1.有event system * 2.camera上有raycaste * 3.image上有raycaste target * 4.canvas上有graphic raycater >![](https://i.imgur.com/u0wwQuq.png) ## :warning:[預設visaul studio code跑掉] >![](https://i.imgur.com/XBpkbnf.png)