#运动 c unity3d
2018-03-29 17:30:23 hellowangld 阅读数 236
  1. 游戏对象运动的本质是什么?
    运动的本质是游戏对象通过脚本变化其(position)位置,(rotation)欧拉角,(scale)形状。
  2. 请用三种方法以上方法,实现物体的抛物线运动。(如,修改Transform属性,使用向量Vector3的方法…)
  3. 改变Transform属性:

    public float Power = 10;//这个代表发射时的速度/力度等,可以通过此来模拟不同的力大小
    
    public float Angle = 45;//发射的角度,这个就不用解释了吧
    
    public float Gravity = -10;//这个代表重力加速度
    
    
    
    private Vector3 MoveSpeed;//初速度向量
    
    private Vector3 GritySpeed = Vector3.zero;//重力的速度向量,t时为0
    
    private float dTime;//已经过去的时间
    
    private Vector3 currentAngle;
    
    // Use this for initialization
    
    void Start()
    
    {
    
        //通过一个公式计算出初速度向量
    
        //角度*力度
    
        MoveSpeed = Quaternion.Euler(new Vector3(0, 0, Angle)) * Vector3.right * Power;
    
        currentAngle = Vector3.zero;
    
    }
    
    // Update is called once per frame
    
    void FixedUpdate()
    
    {
    
        //计算物体的重力速度
    
        //v = at ;
    
        GritySpeed.y = Gravity * (dTime += Time.fixedDeltaTime);
    
        //位移模拟轨迹
    
        transform.position += (MoveSpeed + GritySpeed) * Time.fixedDeltaTime;
    
        currentAngle.z = Mathf.Atan((MoveSpeed.y + GritySpeed.y) / MoveSpeed.x) * Mathf.Rad2Deg;
    
        transform.eulerAngles = currentAngle;
    
    }
    1. 使用Translate平移坐标,同时改变x,y方向的位置以及通过重力改变y方向的位置:

      public float g=-10;//重力加速度
      private Vector3 speed;//初速度向量
      private Vector3 Gravity;//重力向量
      void Start () {
      Gravity = Vector3.zero;//重力初始速度为0
      speed = new Vector3(10,10,0);
      }
      private float dTime=0;
      // Update is called once per frame
      void FixedUpdate () {
      
      Gravity.y = g * (dTime += Time.fixedDeltaTime);//v=at
      //模拟位移
      transform.Translate(speed*Time.fixedDeltaTime);
      transform.Translate(Gravity * Time.fixedDeltaTime);
      }
  4. 使用Vector3的方法:
    C#
    Vector3 center = (sunrise.position + sunset.position) * 0.5F;
    //找中心点
    center -= new Vector3(0, 1, 0);
    //求出新的中心点到向量a和向量b的向量
    Vector3 riseRelCenter = sunrise.position - center;
    Vector3 setRelCenter = sunset.position - center;
    transform.position = Vector3.Slerp(riseRelCenter, setRelCenter, journeyTime);
    //对起始点和结束点修正
    transform.position += center;
    //说实话,这个方法使用起来是真的麻烦。

  5. 使用rigid body对物体施加一个重力效果而不用自己实现重力使物体做抛物线:

    private Vector3 speed;
    public float power;
    public float angle;
    // Use this for initialization
    void Start () {
        speed = Quaternion.Euler (new Vector3 (0, 0, angle)) * Vector3.right * power;
    }
    
    // Update is called once per frame
    void Update () {
        transform.position += speed * Time.deltaTime;
    }
    
    ![这里写图片描述](https://img-blog.csdn.net/20180330102443677?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlbGxvd2FuZ2xk/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
    
  6. 写一个程序,实现一个完整的太阳系, 其他星球围绕太阳的转速必须不一样,且不在一个法平面上。
public Transform mercury;
    public Transform venus;
    public Transform earth;
    public Transform mars;
    public Transform jupiter;
    public Transform saturn;
    public Transform uranus;
    public Transform neptune;
    void Start () {
        mercury.position = new Vector3 (3, 0, 0);
        venus.position = new Vector3 (-5, 0, 0);
        earth.position = new Vector3 (7, 0, 0);
        mars.position = new Vector3 (-9, 0, 0);
        jupiter.position = new Vector3 (-11, 0, 0);
        saturn.position = new Vector3 (13, 0, 0);
        uranus.position = new Vector3 (15, 0, 0);
        neptune.position = new Vector3 (-17, 0, 0);
    }

    void Update () {
        earth.RotateAround (this.transform.position, new Vector3(0, 0.99f, 0), 30 * Time.deltaTime);
        mercury.RotateAround (this.transform.position, new Vector3(0, 2.11f, 0), 47 * Time.deltaTime);
        venus.RotateAround (this.transform.position, new Vector3(0, 3.23f, 0), 35 * Time.deltaTime);
        mars.RotateAround (this.transform.position, new Vector3(0, 4.34f, 0), 24 * Time.deltaTime);
        jupiter.RotateAround (this.transform.position, new Vector3(0, 1.02f, 0), 13 * Time.deltaTime);
        saturn.RotateAround (this.transform.position, new Vector3(0, 0.98f, 0), 9 * Time.deltaTime);
        uranus.RotateAround (this.transform.position, new Vector3(0, 0.97f, 0),  6 * Time.deltaTime);
        neptune.RotateAround (this.transform.position, new Vector3(0, 0.96f, 0), 5 * Time.deltaTime);
        earth.Rotate (Vector3.up * Time.deltaTime * 250);
        mercury.Rotate (Vector3.up * Time.deltaTime * 300);
        venus.Rotate (Vector3.up * Time.deltaTime * 280);
        mars.Rotate (Vector3.up * Time.deltaTime * 220);
        jupiter.Rotate (Vector3.up * Time.deltaTime * 180);
        saturn.Rotate (Vector3.up * Time.deltaTime * 160);
        uranus.Rotate (Vector3.up * Time.deltaTime * 150);
        neptune.Rotate (Vector3.up * Time.deltaTime * 140);
    }

对于游戏牧师与魔鬼

  1. 游戏中提及的对象有牧师,魔鬼,船,河岸,河水。
  2. 玩家动作表:
项目 条件
上船 船已经靠岸且船上至少有一名角色
下船 船上至少有一名角色
游戏胜利 所有牧师与魔鬼均到达对岸
游戏失败 任意一边的魔鬼数量大于牧师数量

关于游戏的详细信息请参考我的具体的博客:牧师与魔鬼

2016-10-12 09:55:55 qq_28221881 阅读数 3107

把此脚本挂在cube上,然后把另一个cube拖到target上,把这两个物体之间设有一段距离,然后运行,就可看到效果。


using UnityEngine;
using System.Collections;

public class Parabola : MonoBehaviour {

    public GameObject target;

    public float speed = 10.0f;

    private float distanceToTarget;

    private bool isMove = true;

    void Start()
    {
        distanceToTarget = Vector3.Distance(this.transform.position, target.transform.position);
        StartCoroutine(Shoot());
    }

   private  IEnumerator Shoot()
    {
       while (isMove )
       {
           Vector3 targetPos = target.transform.position;

           this.transform.LookAt(targetPos);

           float angle = Mathf.Min(1, Vector3.Distance(this.transform.position, targetPos) / distanceToTarget) * 45;

           this.transform.rotation = this.transform.rotation * Quaternion.Euler(Mathf.Clamp(-angle, -42, 42), 0, 0);

           float currentDist = Vector3.Distance(this.transform.position, target.transform.position);

           if(currentDist <0.5f)
           {
               isMove = false;
           }
           this.transform.Translate(Vector3.forward * Mathf.Min(speed * Time.deltaTime, currentDist));
           yield return null;
       }
    }
}


2018-12-29 10:18:06 PangNanGua 阅读数 197

摄影常用的一招就是延时摄影,以使运动的物体产生运动模糊。

摄影技巧为:1,三角架固定相机;2,调长曝光时间;3,对象有运动物体和静止物体参照

用了延时摄影,照片会产生艺术感,见下图(2015年1月 拍摄于上海陆家嘴)

 

游戏方面可喜的是Unity3d也可以实现类似效果,先看效果图

第一张为无运动模糊

第二张为有运动模糊:主体人物清晰,场景运动

第三张为第二张gif中的一帧

第四张为有运动模糊:摄像机不动,人物动的效果(凌波微步)

原理:

累积缓冲区:允许在渲染到颜色缓冲区之后,不是把结果显示到窗口上,而是把内容复制到累积缓冲区,这样就可以把颜色缓冲区与累积缓冲区中的内容反复进行混合,可以用来进行模糊处理和抗锯齿。

我们代码的实现是利用了一块累积缓存来混合多张连续的图像。我们不断的不当前图像叠加到之前渲染好的图像中。

 

shader代码

Shader "mgo/motion_blur" 
{
	Properties
	{
		_MainTex("Texture", 2D) = "white" {}
		_BlurSize("_BlurSize", range(0.001, 0.999)) = 0.9
	}

	SubShader
	{
		Tags{ "RenderType" = "Opaque" }
		
		ZTest Off
		cull Off
		ZWrite Off
		Blend SrcAlpha OneMinusSrcAlpha

		Pass
		{
			Name "Main"
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"

			struct appdata {
				float4 vertex:POSITION;
				float2 uv:TEXCOORD0;
			};

			struct v2f
			{
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
			};

			uniform sampler2D _MainTex;
			uniform half _BlurSize;

			v2f vert(appdata v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed4 color = tex2D(_MainTex,i.uv);
				//降低中心人物的运动模糊start
				float r = sqrt(pow(i.uv.x-0.5,2) + pow(i.uv.y-0.6,2));
				float a = _BlurSize * pow((1 - r + 0.01), 5);
				if (a < 1 - _BlurSize)
				{
					a = 1 - _BlurSize;
				}
				color.a = a;
				//降低中心人物的运动模糊end

				//color.a = 1 - _BlurSize;
				return color;
			}
			ENDCG
		}
		
	}
}

 c#代码

using UnityEngine;

namespace GameBase.Effect
{
    public class MotionBlurEffect : ImageEffectBase
    {

        [SerializeField]
        [Range(0.001f, 0.999f)]
        private float _blurSize = 0.9f;


        private void OnEnable()
        {
            material.SetFloat("_BlurSize",  _blurSize);
        }

        protected override void OnDisable()
        {
            base.OnDisable();
            RenderTexture.ReleaseTemporary(_accumulationRT);
            _accumulationRT = null;
        }

        private RenderTexture _accumulationRT;

        void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            if(_accumulationRT == null || _accumulationRT.width != source.width || _accumulationRT.height != source.height)
            {
                if(_accumulationRT != null)
                    RenderTexture.ReleaseTemporary(_accumulationRT);
                _accumulationRT = RenderTexture.GetTemporary(source.width, source.height, 0, source.format);
                _accumulationRT.hideFlags = HideFlags.HideAndDontSave;
                Graphics.Blit(source, _accumulationRT);
            }
            _accumulationRT.MarkRestoreExpected();//性能开销很大,看下官方文档
            Graphics.Blit(source, _accumulationRT, material);
            Graphics.Blit(_accumulationRT, destination);
        }
    }
}

 

2012-05-07 23:09:31 jkan2001 阅读数 2745

    在Unity3D中,可以通过两种方式利用U3D的物理引擎使一个Rigidbody运动:

    1 通过Addforce给Rigidbody作用力使其运动。

    2 直接设置Rigidbody的velocity使其具有一定的速度。

    采用方法2可以更加精确的控制刚体的运动速度,个人在设计车辆运动的时候比较习惯用这种方式来控制车辆的运动速度。但为了达到一个平滑加速的效果(设置Velocity会使刚体的速度瞬间达到某个值),需要借助Mathf.Lerp()函数来实现速度随时间的逐步增加。

    对于方法1,个人感觉更加适合用于如火箭升空,子弹射击等效果。

2019-03-15 17:31:01 luoyikun 阅读数 132
Shader "Custom/GhostOnly_Transparent" 
{
	Properties 
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_GhostColor ("Ghost Color", Color) = (0, 1, 0, 1)
		_Pow ("Pow Factor", int) = 2
	}
	
	SubShader 
	{
		Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
		LOD 200
		
		Zwrite Off
        Ztest Always
        Blend SrcAlpha One
		CGPROGRAM
		#pragma surface surf Unlit keepalpha
        
        sampler2D _MainTex;
		half4 _GhostColor;
		int _Pow;

		struct Input 
		{
		    float3 viewDir;
		    float2 uv_MainTex;
		};
		
		fixed4 LightingUnlit(SurfaceOutput s, fixed3 lightDir, fixed atten)
		 {
		     fixed4 c;
		     c.rgb = s.Albedo; 
		     c.a = s.Alpha;
		     return c;
		 }

		void surf (Input IN, inout SurfaceOutput o) 
		{
		    half4 c = tex2D (_MainTex, IN.uv_MainTex);
		    float3 worldNormal = WorldNormalVector(IN, o.Normal);
			o.Albedo = _GhostColor.rgb;
			
			half alpha = 1.0 - saturate(dot (normalize(IN.viewDir), worldNormal));
			alpha = pow(alpha, _Pow);
			o.Alpha = c.a * _GhostColor.a * alpha;
		}
		ENDCG
	} 
	FallBack "Diffuse"
}

挂载脚本到需要的残影的GameObject上

using UnityEngine;
using System.Collections;

public class GhostShadow : MonoBehaviour {
    public Color shadowColor;
    //持续时间
    public float duration = 2f;
    //创建新残影间隔
    public float interval = 0.1f;
    
    //网格数据
    SkinnedMeshRenderer[] meshRender;

    //X-ray
    Shader ghostShader;

    void Start()
    {
        //获取身上所有的Mesh
        meshRender = this.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
        ghostShader = Shader.Find("Custom/GhostOnly_Transparent");
    }

    private float lastTime = 0;

    private Vector3 lastPos = Vector3.zero;

    void Update()
    {
        //人物有位移才创建残影
        if (lastPos == this.transform.position)
        {
            return;
        }
        lastPos = this.transform.position;
        if (Time.time - lastTime < interval)
        {//残影间隔时间
            return;
        }
        lastTime = Time.time;

        if (meshRender == null)
            return;
        for (int i = 0; i < meshRender.Length; i++)
        {
            Mesh mesh = new Mesh();
            meshRender[i].BakeMesh(mesh);

            GameObject go = new GameObject();
            go.hideFlags = HideFlags.HideAndDontSave;

            GhostItem item = go.AddComponent<GhostItem>();//控制残影消失
            item.duration = duration;
            item.deleteTime = Time.time + duration;

            MeshFilter filter = go.AddComponent<MeshFilter>();
            filter.mesh = mesh;

            MeshRenderer meshRen = go.AddComponent<MeshRenderer>();

            meshRen.material = meshRender[i].material;
            meshRen.material.shader = ghostShader;
            meshRen.material.SetInt("_Pow", -10);
            shadowColor.a = 1;
            meshRen.material.SetColor("_GhostColor", shadowColor);

            go.transform.localScale = meshRender[i].transform.localScale;
            go.transform.position = meshRender[i].transform.position;
            go.transform.rotation = meshRender[i].transform.rotation;

            item.meshRenderer = meshRen;
        }
    }
}

using UnityEngine;
using System.Collections;

public class GhostItem : MonoBehaviour {

    //持续时间
    public float duration;
    //销毁时间
    public float deleteTime;

    public MeshRenderer meshRenderer;

    void Update()
    {
        float tempTime = deleteTime - Time.time;
        if (tempTime <= 0)
        {//到时间就销毁
            GameObject.Destroy(this.gameObject);
        }
        else if (meshRenderer.material)
        {
            meshRenderer.material.SetInt("_Pow", meshRenderer.material.GetInt("_Pow") + 1);
        }

    }
}

在这里插入图片描述

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