2019-01-26 17:04:19 SnoopyNa2Co3 阅读数 720

最近要搞个效果就是屏幕周围要有种向后拉的感觉

其实原理是uv偏移,就是越往里的偏移越少,越往外偏移越大

实现:就是算uv和拉伸中心点距离来计算偏移

 

其实这个效果是全屏效果,靠近中心点位置也会进行偏移,只是偏移的幅度非常小,小到看不见

我这里使用pow几次方来计算,次方越大则越靠近屏幕的强度越少,这样子很小的数值就会接近0

下面是实现的shader


Shader "ScreenEffect/ScreenStretch"
{

	Properties
	{
		_MainTex("Base (RGB)", 2D) = "white" {}
		_WeakFactor("Weak Factor",Range(1,5)) = 0
	}

	CGINCLUDE
	uniform sampler2D _MainTex;
	//拉伸强度
	uniform float _StretchFactor;
	//拉伸中心点xy值(0-1)屏幕空间
	uniform float4 _ScreenPos;
	//衰减强度
	uniform float _WeakFactor;
	#include "UnityCG.cginc"

	fixed4 frag(v2f_img i) : SV_Target
	{
		float2 dir = i.uv - _ScreenPos.xy;
		//这里算出偏移强度,这里引用了几次方运算,_Weak越大则越靠近屏幕点的则拉伸越小
		float power = pow(length(dir), _WeakFactor) * _StretchFactor;
		//这里编译坐标
		float2 Offset = power * normalize(dir);
		float2 uv = i.uv + Offset;
		return tex2D(_MainTex, uv);
	}
	ENDCG

	SubShader
	{
		Pass
		{
			ZTest Always
			Cull Off
			ZWrite Off
			Fog{ Mode off }

			CGPROGRAM
#pragma fragmentoption ARB_precision_hint_fastest 
#pragma vertex vert_img
#pragma fragment frag 
			ENDCG
		}
	}
}

下面是工程地址

链接:https://pan.baidu.com/s/1UpmoOF2ISCyDG1yjl6s30w 
提取码:h0w0 

2015-10-15 16:29:50 vitrol 阅读数 195

unity 

scene

q拖动w选择e旋转r拉伸

wsad前后左右,qe上下

game

播放暂停逐帧,再次点击播放,结束

此时修改只在游戏内,结束后还原

左上角调节游戏长宽比尺寸

standalone 发布时的长宽比

maximize on play 下次全屏显示

stats 显示参数信息

gizmos 显示光源,粒子等信息

2018-10-09 13:30:59 u013032852 阅读数 1359

    最近又开始做unity项目了~具体内容暂且不表,在最后打包的时候遇到了一个很神奇的事情,同样的配置下,打包出来的一系列10几个项目打开时有的按照配置的分辨率展示,有的默认全屏,有的以窗口模式拉伸来全屏(当然是在客户的电脑上)···然后就直接十脸懵逼了···再三检查配置,甚至都在GameManager里面直接通过Screen.SetResolution(1280, 960, false);来强制限制分辨率以及禁用全屏,但是在客户机上还是没有卵用···

    经过多方查找资料,找到了问题的原因,客户机之前打开过同名(ProjectName)的项目,并且当时打开时选了不同的分辨率(或全屏)展示,这些都记录在注册表中,哪怕把之前的项目文件删除,但是注册表是不会清除的,所以总结解决方案如下:

方案一:在打包的时候直接修改(ProjectName),这样就不会去调用注册表中的配置信息,此方法适用于对项目名称没有严格要求的项目;

方案二: 启动exe文件时,按住Alt或者ctrl+shift+b调出控制界面(unity打包默认自动展示,项目需要已经隐藏了),选择想要的分辨率即可;

方案三:直接打开注册表(Win+R ——> 在运行中输入“regedit”),找到HKEY_CURRENT_USER\Software\[company name]\[product name]([company name]是指在unity中设置的开发商名称(默认DefaultCompany),[product name]是指在unity中设置的项目名称),右键删除,之后unity项目就会按照设置的分辨率打开了。

2018-05-15 18:54:38 tianyongheng 阅读数 858

unity 画曲线 两种方式
一是生成点,由点组成线,比较消耗内存
点组成曲线的Demo 下载地址:https://download.csdn.net/download/tianyongheng/10423694
1.新建Panel
2.在Panel 下新建 Image命名为 line,width=0,height=0;x,y=0;
3.在line 下新建 image 命名为linePointEnd,
4. 在canvas下新建image,命名target;新建image,命名为point

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour {
    public Transform point;
    public Transform lineEndPoint;
    public Transform lineRoot;
    public Transform target;
    public List<Transform> listLine = new List<Transform>();
    float distance = 1;
    // Use this for initialization
    void Start () {
        DrawLine();

    }

    // Update is called once per frame
    void Update () {
        ComputeZoom();

    }
    private void ComputeZoom()
    {

        float zoomFactor = Vector3.Distance(lineRoot.localPosition, lineEndPoint.localPosition) / distance;
        if (listLine.Count > 0)
        {
            Vector3 v = (listLine[listLine.Count - 1].localPosition - lineRoot.localPosition);
            Vector3 v2 = lineEndPoint.localPosition - lineRoot.localPosition;

            lineRoot.localRotation = Quaternion.FromToRotation(v, v2);
        }
        lineRoot.localScale = new Vector3(zoomFactor, zoomFactor, 1);
    }
    void DrawLine()
    {
        lineEndPoint = point;
        listLine.Clear();
        //设置缩放系数        
        distance = Vector3.Distance(lineRoot.localPosition, lineEndPoint.localPosition);
        Vector3[] pos = null;
        if (distance > 300)
        {
            pos = CusCurve.GetCrvePaths(new Vector3[] { lineRoot.localPosition, lineEndPoint.GetComponent<RectTransform>().anchoredPosition3D }, 0.5f, 100, 8, 2);
        }
        else
        {
            pos = CusCurve.GetCrvePaths(new Vector3[] { lineRoot.localPosition, lineEndPoint.GetComponent<RectTransform>().anchoredPosition3D }, 8, 2);
        }

        for (int i = 0; i < pos.Length; i++)
        {
            // Transform t = PoolMapNotManager.Instance.GetPoint(data.isTimeout==0?new Color(48,197,220,255)/255:ExtendColor.ColorRed);
            Transform t = Instantiate<Transform>(point);
            t.SetParent(lineRoot);
            t.localScale = Vector3.one;
            t.GetComponent<RectTransform>().anchoredPosition3D = pos[i];
            listLine.Add(t);
        }
    }
}

二是用曲线图片方式解决
曲线图片Demo 下载地址

https://download.csdn.net/download/tianyongheng/10416443
采用第二种:
1.新建 Panel 锚点拉伸全屏
2.新建Panel 命名为note锚点设置中心 width =0;height=0;
3.新建Panel 命名为lineRoot 锚点设置为中心 width =0;height=0;
4.在lineRoot 下新建image 锚点设置左下角,将曲线图片添加给Image组件, 点击 SetNativeSize
5.在lineRoot 下新建image 命名为lineEndPoint设置锚点中心,将lineEndPoint拖动到曲线终点重合
6.在note节点下新建Image 命名为target设置锚点中心,将target位置设置任意

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour {
    public Transform line;
    public Transform target;
    public Transform lineEnd;
    private Vector3 lastpos;
    private float distance = 1;
    // Use this for initialization
    void Start () {
        distance = Vector3.Distance(line.localPosition, lineEnd.localPosition);
        Debug.Log("distance:" + distance);
    }
    void Compute()
    {
        float zoomFactor = Vector3.Distance(line.localPosition, target.localPosition) / distance;
        Debug.Log("zoomFactor:" + zoomFactor);
        Vector2 a = lineEnd.localPosition - line.localPosition;
        Vector2 b = target.localPosition - line.localPosition;
        line.localRotation = Quaternion.FromToRotation(a, b);
        line.localScale = new Vector3(zoomFactor, zoomFactor, 1);
    }
    // Update is called once per frame
    void Update () {

            Compute();
            lastpos = target.position;



    }
}
2016-04-11 17:01:00 weixin_30500289 阅读数 2

给全屏后不在乎拉伸变形仍想让画面占满屏幕的朋友,网上搜了一上午,实在是没有相关的资料,只能自己琢磨了。

使用Canvas Scaler在全屏后Unity虽然会为我们自动拉伸UI,但拉伸后仍然保持我们在Unity中设置的高宽比。屏幕中的黑边需要通过代码来对UI的内容进行拉伸填充。

下面是我的测试环境:

Unity3D 5.3.4

Win 10 64bit

 

测试中我Unity设置成了自动根据屏幕宽度进行拉伸,这样需要调整UI的高度来填充画面上下出现的黑边了。

开发中使用的分辨率是16:9的,但实际发布运行后肯能会在5:3,16:10甚至是2:1的显示器上运行,这样在根据上面的设置,unity会自动横向拉伸,但在画面的上下会出现黑边。

把下面的代码挂在Camera或者Canvas上的脚本的Start函数里,UI便会自动上下拉伸把画面上下部分的黑边给填充掉。

        StandarRatio = new Vector3[RechangeForms.Length];
        float referenceRatio = 16f/9f;
        float currentRatio =( (float)Screen.width /  (float)Screen.height);
        for (int i = 0; i < RechangeForms.Length; i++)
        {
            StandarRatio[i] = RechangeForms[i].transform.localScale;
            float yFactor = StandarRatio[i].y * (referenceRatio / currentRatio);
            float posYFactor = RechangeForms[i].transform.position.y * (referenceRatio / currentRatio);
            RechangeForms[i].transform.DOScaleY(yFactor, 0.0f);
            RechangeForms[i].transform.DOMoveY(posYFactor, 0.0f);
        }    

StandarRatio是一个Vector3的数组,用来存储元素在拉伸前的Scale的值,RechangeForms是需要被拉伸的元素的集合,是个gameobject数组。

代码是通过调整UI元素的Scale中Y的值来实现填充黑边的。

使用到的数学公式:新的YScale=原始YScale*(参考分辨率的比率/实际分辨率的比率)。

这里有个额外的问题,就是在调整UI元素的Scale的Y值后,该元素的中心点左边也改变了,所以也需要做相应的调整。公式同上。(此处也可能是由于我自身项目的原因引起的)

 

完成上述步骤后,可以在Unity的预览窗口中切换成各种比利的显示器进行测试,可以看到原来上下出现的黑边已经被拉伸过后的UI元素给填充上了(虽然UI变形了,但黑边没了)。

 

转载于:https://www.cnblogs.com/li0803/p/5379087.html

没有更多推荐了,返回首页