效果
在书本翻页的效果中,需要选择plane上的点,来进行翻页。 这里把鼠标选中的点映射到plane的uv中
思路
将鼠标射线触碰到plane上的点的世界坐标,转换为plane模型自身坐标。再除以模型的大小即可
如果直接给shader传入世界坐标,还需要再顶点着色器中变换到模型空间。 所以 在plane的子物体下挂空物体,将世界坐标给该物体,再讲该物体的本地坐标(即模型空间)传给shader
优化
同样的思路可以用在不规则模型上,即 获取到的世界坐标的点,转换到模型空间下,然后找 最近的顶点。使用该顶点的uv即可。 问题: 找到的点不一定就是顶点,可能是面上的点
代码
脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class PlaneMouseHelper : MonoBehaviour
{
private Material mat;
public Transform Pos0;
public Camera rayCamera;
private void Start()
{
mat = GetComponent<Renderer>().sharedMaterial;
if (rayCamera == null)
rayCamera = Camera.main;
Pos0 = transform.GetChild(0);
}
private void Update()
{
Ray ray = rayCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray,out hit))
{
if (Input.GetMouseButton(0))
{
if (hit.transform == transform)
{
Pos0.position = hit.point;
mat.SetVector("_MouseModePos", Pos0.localPosition);
}
}
}
}
}
shader:
Shader "Unlit/PlaneGetMousePos01"
{
Properties
{
_MainTex("Main Texture",2D)="white"{}
_MouseModePos ("MousePos in ModeSpace", Vector) = (0,0,0,0)
_PlaneScale("Plane XY",Vector)=(-5,-5,10,10)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float2 uv_mouse:TEXCOORD1;
};
float4 _MouseModePos;
float4 _PlaneScale;
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv = 1-o.uv;
float2 uvTemp = _MouseModePos.xz - _PlaneScale.xy;
o.uv_mouse = uvTemp/_PlaneScale.zw;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
if(lerp(i.uv_mouse.x,i.uv_mouse.y,0.1)<0.3){
if(i.uv.x < i.uv_mouse.x && i.uv.y < i.uv_mouse.y)
col *= 0;
}
return col;
}
ENDCG
}
}
}
|