博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
VR_物体边框高亮(变红)
阅读量:5738 次
发布时间:2019-06-18

本文共 20286 字,大约阅读时间需要 67 分钟。

效果如图:

 

实现脚本:

给要高亮的物体加上脚本:

gameObject.GetComponent<SpectrumController>().enabled = true;

取消高亮:

gameObject.GetComponent<SpectrumController>().enabled = False;

 

 

using UnityEngine;using System.Collections;public class SpectrumController : HighlightingController{    public float speed = 0;//速度        private readonly int period = 1530;    private float counter = 0f;        protected override void AfterUpdate()    {        base.AfterUpdate();                int val = (int)counter;        Color col = new Color(GetColorValue(1020, val), GetColorValue(0, val), GetColorValue(510, val), 1f);//边框颜色                ho.ConstantOnImmediate(col);                counter += Time.deltaTime * speed;        counter %= period;    }        // Some color spectrum magic    float GetColorValue(int offset, int x)    {        int o = 0;        x = (x - offset) % period;        if (x < 0)        {            x += period;        }                if (x < 255)        {            o = x;        }                if (x >= 255 && x < 765)        {            o = 255;        }                if (x >= 765 && x < 1020)        {            o = 1020 - x;        }                return (float) o / 255f;    }}

 

 

 

 

using UnityEngine;using System.Collections;using System.Collections.Generic;public class HighlightableObject : MonoBehaviour{    #region Editable Fields    // Builtin layer reserved for the highlighting    public static int highlightingLayer = 7;        // Constant highlighting turning on speed    private static float constantOnSpeed = 4.5f;        // Constant highlighting turning off speed    private static float constantOffSpeed = 4f;        // Default transparent cutoff value used for shaders without _Cutoff property    private static float transparentCutoff = 0.5f;    #endregion        #region Private Fields    // 2 * PI constant required for flashing    private const float doublePI = 2f * Mathf.PI;        // Cached materials    private List
highlightableRenderers; // Cached layers of highlightable objects private int[] layersCache; // Need to reinit materials flag private bool materialsIsDirty = true; // Current state of highlighting private bool currentState = false; // Current materials highlighting color private Color currentColor; // Transition is active flag private bool transitionActive = false; // Current transition value private float transitionValue = 0f; // Flashing frequency private float flashingFreq = 2f; // One-frame highlighting flag private bool once = false; // One-frame highlighting color private Color onceColor = Color.red; // Flashing state flag private bool flashing = false; // Flashing from color private Color flashingColorMin = new Color(0.0f, 1.0f, 1.0f, 0.0f); // Flashing to color private Color flashingColorMax = new Color(0.0f, 1.0f, 1.0f, 1.0f); // Constant highlighting state flag private bool constantly = false; // Constant highlighting color private Color constantColor = Color.yellow; // Occluder private bool occluder = false; // Currently used shaders ZWriting state private bool zWrite = false; // Occlusion color (DON'T TOUCH THIS!) private readonly Color occluderColor = new Color(0.0f, 0.0f, 0.0f, 0.005f); // private Material highlightingMaterial { get { return zWrite ? opaqueZMaterial : opaqueMaterial; } } // Common (for this component) replacement material for opaque geometry highlighting private Material _opaqueMaterial; private Material opaqueMaterial { get { if (_opaqueMaterial == null) { _opaqueMaterial = new Material(opaqueShader); _opaqueMaterial.hideFlags = HideFlags.HideAndDontSave; } return _opaqueMaterial; } } // Common (for this component) replacement material for opaque geometry highlighting with Z-Buffer writing enabled private Material _opaqueZMaterial; private Material opaqueZMaterial { get { if (_opaqueZMaterial == null) { _opaqueZMaterial = new Material(opaqueZShader); _opaqueZMaterial.hideFlags = HideFlags.HideAndDontSave; } return _opaqueZMaterial; } } // private static Shader _opaqueShader; private static Shader opaqueShader { get { if (_opaqueShader == null) { _opaqueShader = Shader.Find("Hidden/Highlighted/StencilOpaque"); } return _opaqueShader; } } // private static Shader _transparentShader; public static Shader transparentShader { get { if (_transparentShader == null) { _transparentShader = Shader.Find("Hidden/Highlighted/StencilTransparent"); } return _transparentShader; } } // private static Shader _opaqueZShader; private static Shader opaqueZShader { get { if (_opaqueZShader == null) { _opaqueZShader = Shader.Find("Hidden/Highlighted/StencilOpaqueZ"); } return _opaqueZShader; } } // private static Shader _transparentZShader; private static Shader transparentZShader { get { if (_transparentZShader == null) { _transparentZShader = Shader.Find("Hidden/Highlighted/StencilTransparentZ"); } return _transparentZShader; } } #endregion #region Common // Internal class for renderers caching private class HighlightingRendererCache { public Renderer rendererCached; public GameObject goCached; private Material[] sourceMaterials; private Material[] replacementMaterials; private List
transparentMaterialIndexes; // Constructor public HighlightingRendererCache(Renderer rend, Material[] mats, Material sharedOpaqueMaterial, bool writeDepth) { rendererCached = rend; goCached = rend.gameObject; sourceMaterials = mats; replacementMaterials = new Material[mats.Length]; transparentMaterialIndexes = new List
(); for (int i = 0; i < mats.Length; i++) { Material sourceMat = mats[i]; if (sourceMat == null) { continue; } string tag = sourceMat.GetTag("RenderType", true); if (tag == "Transparent" || tag == "TransparentCutout") { Material replacementMat = new Material(writeDepth ? transparentZShader : transparentShader); if (sourceMat.HasProperty("_MainTex")) { replacementMat.SetTexture("_MainTex", sourceMat.mainTexture); replacementMat.SetTextureOffset("_MainTex", sourceMat.mainTextureOffset); replacementMat.SetTextureScale("_MainTex", sourceMat.mainTextureScale); } replacementMat.SetFloat("_Cutoff", sourceMat.HasProperty("_Cutoff") ? sourceMat.GetFloat("_Cutoff") : transparentCutoff); replacementMaterials[i] = replacementMat; transparentMaterialIndexes.Add(i); } else { replacementMaterials[i] = sharedOpaqueMaterial; } } } // Based on given state variable, replaces materials of this cached renderer to the highlighted ones and back public void SetState(bool state) { rendererCached.sharedMaterials = state ? replacementMaterials : sourceMaterials; } // Sets given color as the highlighting color on all transparent materials for this cached renderer public void SetColorForTransparent(Color clr) { for (int i = 0; i < transparentMaterialIndexes.Count; i++) { replacementMaterials[transparentMaterialIndexes[i]].SetColor("_Outline", clr); } } } // private void OnEnable() { StartCoroutine(EndOfFrame()); // Subscribe to highlighting event HighlightingEffect.highlightingEvent += UpdateEventHandler; } // private void OnDisable() { StopAllCoroutines(); // Unsubscribe from highlighting event HighlightingEffect.highlightingEvent -= UpdateEventHandler; // Clear cached renderers if (highlightableRenderers != null) { highlightableRenderers.Clear(); } // Reset highlighting parameters to default values layersCache = null; materialsIsDirty = true; currentState = false; currentColor = Color.clear; transitionActive = false; transitionValue = 0f; once = false; flashing = false; constantly = false; occluder = false; zWrite = false; /* // Reset custom parameters of the highlighting onceColor = Color.red; flashingColorMin = new Color(0f, 1f, 1f, 0f); flashingColorMax = new Color(0f, 1f, 1f, 1f); flashingFreq = 2f; constantColor = Color.yellow; */ if (_opaqueMaterial) { DestroyImmediate(_opaqueMaterial); } if (_opaqueZMaterial) { DestroyImmediate(_opaqueZMaterial); } } #endregion #region Public Methods ///
/// Materials reinitialization. /// Call this method if your highlighted object changed his materials or child objects. /// Can be called multiple times per update - renderers reinitialization will occur only once. /// public void ReinitMaterials() { materialsIsDirty = true; } ///
/// Immediately restore original materials. Obsolete. Use ReinitMaterials() instead. /// public void RestoreMaterials() { Debug.LogWarning("HighlightingSystem : RestoreMaterials() is obsolete. Please use ReinitMaterials() instead."); ReinitMaterials(); } ///
/// Set color for one-frame highlighting mode. /// ///
/// Highlighting color. /// public void OnParams(Color color) { onceColor = color; } ///
/// Turn on one-frame highlighting. /// public void On() { // Highlight object only in this frame once = true; } ///
/// Turn on one-frame highlighting with given color. /// Can be called multiple times per update, color only from the latest call will be used. /// ///
/// Highlighting color. /// public void On(Color color) { // Set new color for one-frame highlighting onceColor = color; On(); } ///
/// Set flashing parameters. /// ///
/// Starting color. /// ///
/// Ending color. /// ///
/// Flashing frequency. /// public void FlashingParams(Color color1, Color color2, float freq) { flashingColorMin = color1; flashingColorMax = color2; flashingFreq = freq; } ///
/// Turn on flashing. /// public void FlashingOn() { flashing = true; } ///
/// Turn on flashing from color1 to color2. /// ///
/// Starting color. /// ///
/// Ending color. /// public void FlashingOn(Color color1, Color color2) { flashingColorMin = color1; flashingColorMax = color2; FlashingOn(); } ///
/// Turn on flashing from color1 to color2 with given frequency. /// ///
/// Starting color. /// ///
/// Ending color. /// ///
/// Flashing frequency. /// public void FlashingOn(Color color1, Color color2, float freq) { flashingFreq = freq; FlashingOn(color1, color2); } ///
/// Turn on flashing with given frequency. /// ///
/// Flashing frequency. /// public void FlashingOn(float freq) { flashingFreq = freq; FlashingOn(); } ///
/// Turn off flashing. /// public void FlashingOff() { flashing = false; } ///
/// Switch flashing mode. /// public void FlashingSwitch() { flashing = !flashing; } ///
/// Set constant highlighting color. /// ///
/// Constant highlighting color. /// public void ConstantParams(Color color) { constantColor = color; } ///
/// Fade in constant highlighting. /// public void ConstantOn() { // Enable constant highlighting constantly = true; // Start transition transitionActive = true; } ///
/// Fade in constant highlighting with given color. /// ///
/// Constant highlighting color. /// public void ConstantOn(Color color) { // Set constant highlighting color constantColor = color; ConstantOn(); } ///
/// Fade out constant highlighting. /// public void ConstantOff() { // Disable constant highlighting constantly = false; // Start transition transitionActive = true; } ///
/// Switch Constant Highlighting. /// public void ConstantSwitch() { // Switch constant highlighting constantly = !constantly; // Start transition transitionActive = true; } ///
/// Turn on constant highlighting immediately (without fading in). /// public void ConstantOnImmediate() { constantly = true; // Set transition value to 1 transitionValue = 1f; // Stop transition transitionActive = false; } ///
/// Turn on constant highlighting with given color immediately (without fading in). /// ///
/// Constant highlighting color. /// public void ConstantOnImmediate(Color color) { // Set constant highlighting color constantColor = color; ConstantOnImmediate(); } ///
/// Turn off constant highlighting immediately (without fading out). /// public void ConstantOffImmediate() { constantly = false; // Set transition value to 0 transitionValue = 0f; // Stop transition transitionActive = false; } ///
/// Switch constant highlighting immediately (without fading in/out). /// public void ConstantSwitchImmediate() { constantly = !constantly; // Set transition value to the final value transitionValue = constantly ? 1f : 0f; // Stop transition transitionActive = false; } ///
/// Enable occluder mode /// public void OccluderOn() { occluder = true; } ///
/// Disable occluder mode /// public void OccluderOff() { occluder = false; } ///
/// Switch occluder mode /// public void OccluderSwitch() { occluder = !occluder; } ///
/// Turn off all types of highlighting. /// public void Off() { // Turn off all types of highlighting once = false; flashing = false; constantly = false; // Set transition value to 0 transitionValue = 0f; // Stop transition transitionActive = false; } ///
/// Destroy this HighlightableObject component. /// public void Die() { Destroy(this); } #endregion #region Private Methods // Materials initialisation private void InitMaterials(bool writeDepth) { currentState = false; zWrite = writeDepth; highlightableRenderers = new List
(); MeshRenderer[] mr = GetComponentsInChildren
(); CacheRenderers(mr); SkinnedMeshRenderer[] smr = GetComponentsInChildren
(); CacheRenderers(smr); #if !UNITY_FLASH //ClothRenderer[] cr = GetComponentsInChildren
(); //CacheRenderers(cr); #endif currentState = false; materialsIsDirty = false; currentColor = Color.clear; } // Cache given renderers properties private void CacheRenderers(Renderer[] renderers) { for (int i = 0; i < renderers.Length; i++) { Material[] materials = renderers[i].sharedMaterials; if (materials != null) { highlightableRenderers.Add(new HighlightingRendererCache(renderers[i], materials, highlightingMaterial, zWrite)); } } } // Update highlighting color to a given value private void SetColor(Color c) { if (currentColor == c) { return; } if (zWrite) { opaqueZMaterial.SetColor("_Outline", c); } else { opaqueMaterial.SetColor("_Outline", c); } for (int i = 0; i < highlightableRenderers.Count; i++) { highlightableRenderers[i].SetColorForTransparent(c); } currentColor = c; } // Set new color if needed private void UpdateColors() { // Don't update colors if highlighting is disabled if (currentState == false) { return; } if (occluder) { SetColor(occluderColor); return; } if (once) { SetColor(onceColor); return; } if (flashing) { // Flashing frequency is not affected by Time.timeScale Color c = Color.Lerp(flashingColorMin, flashingColorMax, 0.5f * Mathf.Sin(Time.realtimeSinceStartup * flashingFreq * doublePI) + 0.5f); SetColor(c); return; } if (transitionActive) { Color c = new Color(constantColor.r, constantColor.g, constantColor.b, constantColor.a * transitionValue); SetColor(c); return; } else if (constantly) { SetColor(constantColor); return; } } // Calculate new transition value if needed. private void PerformTransition() { if (transitionActive == false) { return; } float targetValue = constantly ? 1f : 0f; // Is transition finished? if (transitionValue == targetValue) { transitionActive = false; return; } if (Time.timeScale != 0f) { // Calculating delta time untouched by Time.timeScale float unscaledDeltaTime = Time.deltaTime / Time.timeScale; // Calculating new transition value transitionValue += (constantly ? constantOnSpeed : -constantOffSpeed) * unscaledDeltaTime; transitionValue = Mathf.Clamp01(transitionValue); } else { return; } } // Highlighting event handler (main highlighting method) private void UpdateEventHandler(bool trigger, bool writeDepth) { // Update and enable highlighting if (trigger) { // ZWriting state changed? if (zWrite != writeDepth) { materialsIsDirty = true; } // Initialize new materials if needed if (materialsIsDirty) { InitMaterials(writeDepth); } currentState = (once || flashing || constantly || transitionActive || occluder); if (currentState) { UpdateColors(); PerformTransition(); if (highlightableRenderers != null) { layersCache = new int[highlightableRenderers.Count]; for (int i = 0; i < highlightableRenderers.Count; i++) { GameObject go = highlightableRenderers[i].goCached; // cache layer layersCache[i] = go.layer; // temporary set layer to renderable by the highlighting effect camera go.layer = highlightingLayer; highlightableRenderers[i].SetState(true); } } } } // Disable highlighting else { if (currentState && highlightableRenderers != null) { for (int i = 0; i < highlightableRenderers.Count; i++) { highlightableRenderers[i].goCached.layer = layersCache[i]; highlightableRenderers[i].SetState(false); } } } } IEnumerator EndOfFrame() { while (enabled) { yield return new WaitForEndOfFrame(); // Reset one-frame highlighting state after each HighlightingEffect in the scene has finished rendering once = false; } } #endregion}

 

转载于:https://www.cnblogs.com/huang--wei/p/11121056.html

你可能感兴趣的文章
数据传输流程和socket简单操作
查看>>
利用广播实现ip拨号——示例
查看>>
ProbS CF matlab源代码(二分系统)(原创作品,转载注明出处,谢谢!)
查看>>
OC中KVC的注意点
查看>>
JQ入门(至回调函数)
查看>>
【洛天依】几首歌的翻唱(无伴奏)
查看>>
OpenSSL初瞻及本系列的博文的缘由
查看>>
ISO8583接口的详细资料
查看>>
tmux不自动加载配置文件.tmux.conf
查看>>
经验分享:JavaScript小技巧
查看>>
[MOSEK] Stupid things when using mosek
查看>>
程序实例---栈的顺序实现和链式实现
查看>>
服务的使用
查看>>
Oracle 用户与模式
查看>>
MairDB 初始数据库与表 (二)
查看>>
拥在怀里
查看>>
chm文件打开,有目录无内容
查看>>
whereis、find、which、locate的区别
查看>>
一点不懂到小白的linux系统运维经历分享
查看>>
桌面支持--打不开网页上的pdf附件解决办法(ie-tools-compatibility)
查看>>