此文章內容則是...遊戲設計很常用到的第一人稱,雖然Unity官方也很套件可以使用。

但是自己研究後,發現到滿有趣的,有興趣的玩家,不妨也來試試吧。

此功能有使用到Unity Editor 功能哦,請嘗試玩家注意。

 

詳細資料在於Google Blogger 部落格這裡,請點選

 

以下則是這次內容FPS 程式範例:

FPS (第一人稱) 腳本

mpleSmoothMouseLook (攝影機) 腳本

---------

Script (C#):

using UnityEngine;
using System.Collections;
using UnityEditor;

[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]

public class FPS : MonoBehaviour {
    
    [MenuItem("PlayerMode/FPS")]
    static void Fps() {
        GameObject fps = new GameObject("FPS");
        fps.transform.position = Vector3.zero;

        // FPS add component
        fps.AddComponent();

        GameObject cam = new GameObject("Camera");
        cam.transform.parent = fps.transform;

        // Camera add component
        cam.AddComponent();
        cam.AddComponent();
        cam.AddComponent();
        cam.AddComponent();
        cam.AddComponent();
    }

    [SerializeField]
    float speed = 10.0f, gravity = 10.0f, maxVelocityChange = 10f, jumpHeight = 2.0f;
    [SerializeField]
    bool canJump = true;

    private bool grounded = false;

    Rigidbody rigidbody;
    CapsuleCollider playerCollider;

    void Awake(){
        rigidbody = GetComponent();
        rigidbody.freezeRotation = true;
        rigidbody.useGravity = false;
        gameObject.AddComponent();
    }

    void FixedUpdate() {

        if (grounded) {

            // Calculate how fast we should be moving
            Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal") * speed,0, Input.GetAxis("Vertical")* speed);
            targetVelocity = transform.TransformDirection(targetVelocity);

            // Apply a force that attempts to reach our target velocity
            Vector3 velocity = rigidbody.velocity;
            Vector3 velocityChange = (targetVelocity - velocity);
            velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
            velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
            velocityChange.y = 0;
            rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);

            //Jump
            if (canJump && Input.GetButton("Jump"))
                rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
        }
        rigidbody.AddForce(new Vector3(0,-gravity * rigidbody.mass, 0));
        grounded = false;
    }

    void OnCollisionStay()
    {
        grounded = true;
    }

    float CalculateJumpVerticalSpeed() {
        return Mathf.Sqrt(2 * jumpHeight * gravity);
    }
}

 

------------

Script (C#):

using UnityEngine;
using System.Collections;


[AddComponentMenu("Camera/Simple Smooth Mouse Look ")]
public class SimpleSmoothMouseLook : MonoBehaviour {

    Vector2 _mouseAbsolute;
    Vector2 _smoothMouse;

    public Vector2 clampInDegrees = new Vector2(360, 180);
    public bool lockCursor;
    public Vector2 sensitivity = new Vector2(2, 2);
    public Vector2 smoothing = new Vector2(3, 3);
    public Vector2 targetDirection;
    public Vector2 targetCharacterDirection;

    // Assign this if there's a parent object controlling motion, such as a Character Controller.
    // Yaw rotation will affect this object instead of the camera if set.
    public GameObject characterBody;

    void Start()
    {
        // Set target direction to the camera's initial orientation.
        targetDirection = transform.localRotation.eulerAngles;

        // Set target direction for the character body to its inital state.
        if (characterBody) targetCharacterDirection = characterBody.transform.localRotation.eulerAngles;
    }

    void Update()
    {
        // Ensure the cursor is always locked when set
        Screen.lockCursor = lockCursor;

        // Allow the script to clamp based on a desired target value.
        var targetOrientation = Quaternion.Euler(targetDirection);
        var targetCharacterOrientation = Quaternion.Euler(targetCharacterDirection);

        // Get raw mouse input for a cleaner reading on more sensitive mice.
        var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));

        // Scale input against the sensitivity setting and multiply that against the smoothing value.
        mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y));

        // Interpolate mouse movement over time to apply smoothing delta.
        _smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x);
        _smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y);

        // Find the absolute mouse movement value from point zero.
        _mouseAbsolute += _smoothMouse;

        // Clamp and apply the local x value first, so as not to be affected by world transforms.
        if (clampInDegrees.x < 360)
            _mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f);

        var xRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right);
        transform.localRotation = xRotation;

        // Then clamp and apply the global y value.
        if (clampInDegrees.y < 360)
            _mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);

        transform.localRotation *= targetOrientation;

        // If there's a character body that acts as a parent to the camera
        if (characterBody)
        {
            var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, characterBody.transform.up);
            characterBody.transform.localRotation = yRotation;
            characterBody.transform.localRotation *= targetCharacterOrientation;
        }
        else
        {
            var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, transform.InverseTransformDirection(Vector3.up));
            transform.localRotation *= yRotation;
        }
    }
}

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

此文章內容是天氣裡面的龍捲風物理哦。

龍捲風作法,我相信大家都應該知道 可以用粒子系統 (Particle System)及加上旋轉就能形成。

我們馬上來看以下程式碼之範例吧... 

--------------------------

Script (C#):

using UnityEngine;
using System.Collections;

public class Tornado_Main : MonoBehaviour {

    [Tooltip(&quot;This controls the radius of your tornados pull range&quot;)]
    public float radius = 65.28f;
    public float maxRadiusToPullIn = 10;
    [Tooltip(&quot;NEGATIVE NUMBERS ONLY. This pulls objects into the tornado&quot;)]
    public float PullingInPower = -70;
    public float MaxPullingIn = 20;

    Collider[] colliders;

    void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(transform.position, radius);
    }
    
    void Update()
    {
        colliders = Physics.OverlapSphere(transform.position, radius);
        foreach (Collider c in colliders)
        {
            if (c.GetComponent() == null)
            {
                continue;
            }
            Ray ray = new Ray(transform.position, c.transform.position - transform.position);
            RaycastHit hit;
            Physics.Raycast(ray, out hit);
            if (hit.collider.name != c.gameObject.name || hit.distance &lt; MaxPullingIn)
            {
                continue;
            }
            else
            {
                Rigidbody rigidbody = c.GetComponent();
                rigidbody.AddExplosionForce(PullingInPower, transform.position, radius);
            }
        }
    }
}

 

---------------

Script(C#):

using UnityEngine;
using System.Collections;

public class Outer_Tornado : MonoBehaviour
{

    public float radius = 19.48f;
    public float outsideSpeed = 0.7f;
    public float maxPullInLength = 24.96f;
    public float power = 1;


    Collider[] colliders;

    void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(transform.position, radius);
    }

    void Update ()
    {
        transform.RotateAround(transform.parent.transform.position, Vector3.up, outsideSpeed);
        colliders = Physics.OverlapSphere(transform.position, radius);
        foreach (Collider c in colliders)
        {
            if (c.GetComponent() == null)
            {
                continue;
            }
            Rigidbody rigidbody = c.GetComponent();
            Ray ray = new Ray(transform.position, c.transform.position - transform.position);
            RaycastHit hit;
            Physics.Raycast(ray, out hit);
            if (hit.distance &gt; maxPullInLength)
            {
                continue;
            }
            if (c.transform.position.z &gt; 8.5)
            {
                Vector3 Force = new Vector3(transform.position.x - c.transform.position.x, rigidbody.velocity.y / 2, transform.position.z - c.transform.position.z) * power;
                rigidbody.AddForceAtPosition(Force, transform.position);
            }
            rigidbody.AddForceAtPosition((transform.position - c.transform.position) * power, transform.position);
        }
    }
}

 

---------------

結果圖:

成功的話,可以像以下圖片一樣,讓物件飛起來哦....

111.PNG

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

此文章內容則是物件跟隨,遊戲設計當中,可是很常見的功能。

以下則是此文章範例程式:

--------------

Script (c#):

 

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

public class PetFlow : MonoBehaviour {

    public Transform player;
    public float maxDis = 5;

    private SmoothFollowerObj posFollow; // 控制位置平滑移動
    private SmoothFollowerObj lookFollow; // 控制朝向平滑轉換

    public Vector3 posistionVector; // 角色位置移動,方向向量
    public Vector3 lookVector; //角色朝向變化,朝向向量

    private Vector3 lastVelocityDir; // 上一次移動方向
    private Vector3 lastPost; // 之前移動目標位置

    void Start()
    {
        posFollow = new SmoothFollowerObj(0.5f, 0.5f);
        lookFollow = new SmoothFollowerObj(0.1f, 0.1f);
        posFollow.Update(transform.position, 0, true); // 初始位置
        lookFollow.Update(player.transform.position, 0, true);

        posistionVector = new Vector3(0, 0.5f, 1.7f);
        lookVector = new Vector3(0, 0, 1.5f);

        lastVelocityDir = player.transform.forward;
        lastPost = player.transform.position;
    }

    void Update()
    {
        float dis = Vector3.Distance(transform.position, player.position);

        if (dis &gt; maxDis)
            PetMoveFlow();
    }

    // 物件移動
    void PetMoveFlow()
    {
        lastVelocityDir += (player.position - lastPost) * 5;
        lastPost = player.position;

        lastVelocityDir += player.transform.forward * Time.deltaTime;
        lastVelocityDir = lastVelocityDir.normalized;

        Vector3 horizontal = transform.position - player.position;
        Vector3 horizontal2 = horizontal;
        Vector3 vertical = player.up;
        Vector3.OrthoNormalize(ref vertical, ref horizontal);  // https://docs.unity3d.com/ScriptReference/Vector3.OrthoNormalize.html api

        // https://docs.unity3d.com/ScriptReference/Vector3-sqrMagnitude.html api
        if (horizontal.sqrMagnitude &gt; horizontal2.sqrMagnitude)
            horizontal = horizontal2;

        transform.position = posFollow.Update(player.position + horizontal * Mathf.Abs(posistionVector.z)
            + vertical * posistionVector.y, Time.deltaTime);

        horizontal = lastVelocityDir;

        Vector3 look = lookFollow.Update(player.position + horizontal * lookVector.z
            - vertical * lookVector.y, Time.deltaTime);

        // https://docs.unity3d.com/ScriptReference/Quaternion.FromToRotation.html api
        transform.rotation = Quaternion.FromToRotation(transform.forward, look - transform.position) * transform.rotation;
    }
}

class SmoothFollowerObj
{
    private Vector3 targetPosistion; // 目標位置
    private Vector3 position; // 位置
    private Vector3 velocity;  // 速率
    private float smoothingTime; // 平滑時間
    private float prediction; // 預測

    public SmoothFollowerObj(float smoothingTime)
    {
        targetPosistion = Vector3.zero;
        position = Vector3.zero;
        this.smoothingTime = smoothingTime;
        prediction = 1;
    }

    public SmoothFollowerObj(float smoothingTime, float prediction)
    {
        targetPosistion = Vector3.zero;
        position = Vector3.zero;
        this.smoothingTime = smoothingTime;
        this.velocity = velocity;
    }

    // 更新位置資訊
    public Vector3 Update(Vector3 targetPosistionNew, float dataTime)
    {
        Vector3 targetvelocity = (targetPosistionNew - targetPosistion) / dataTime; // 獲取目標移動的方向向量
        targetPosistion = targetPosistionNew;

        float d = Mathf.Min(1, dataTime / smoothingTime);
        velocity = velocity * (1 - d) + (targetPosistion + targetvelocity * prediction - position) * d;

        position += velocity * Time.deltaTime;
        return position;
    }

    // 根據傳輸進來數據, 重置本地參數
    public Vector3 Update(Vector3 targetPosistionNew, float dataTime, bool rest) 
    {
        if (rest)
        {
            targetPosistion = targetPosistionNew;
            position = targetPosistionNew;
            velocity = Vector3.zero;

            return position;
        }

        return Update(targetPosistionNew, dataTime);
    }

    public Vector3 GetPosistion() { return position; }
    public Vector3 GetVelocity() { return velocity; }
}

 

---------------

成功的話....物件會會跟著所指定的位置來做移動哦。

此外...可以利用物件與物件關係(親代)來調整中心點位置。

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

已經好久沒來「痞客邦」來寫關於Unity 技術文章,都在Goolge Blooger 那邊撰寫比較多 

回歸主題...此文章內容是Unity裡面Sprite 裡面的功能。

不多說...直接看程式碼之範例吧

忘了一件事情,此程式碼操作使用到Unity Editor 外掛編輯元件哦。

-----------------

Unity Edtor (C#):

 

 

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

public class SpriteProcessor : EditorWindow
{

    private Vector2 vector2Label;          // 標籤位置(BeginScrollView 用的)
    private GUIStyle style = new GUIStyle();   // GUI 風格
    private string spriteSegmentationType = &quot;&quot;;  // Sprite 分割像素
    private string spriteName = &quot;&quot;;        // Sprite 分格後名稱
    private int spriteTitleNumber = 0;   // 分格後的名稱編號
    private int spriteSegmentationNumber;   // 分割數值字串轉型



    //  呼叫視窗
    [MenuItem(測試/Sprite寫法)]
    public static void spriteWindowSetting()
    {
        SpriteProcessor windows = EditorWindow.GetWindow(typeof(SpriteProcessor), true, &quot;Sprite 自動分割&quot;) as SpriteProcessor;
        windows.Show();
    }

  

    // 選擇貼圖(Sprite)
    static Object[] getSelectTexture()
    {
        return Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);
    }

    void OnGUI()
    {

        style.fontSize = 18;
        style.normal.textColor = Color.white;

        GUI.Label(new Rect(0, 0, 100, 30), &quot;圖片分割&quot;, style);

        // Sprite 分割像素
        GUILayout.BeginArea(new Rect(0, 30, 300, 100));
        GUILayout.BeginHorizontal();
        GUILayout.Label(&quot;Sprite 分割像素&quot;);
        GUILayout.EndHorizontal();
        GUILayout.EndArea();

        // Sprite 分割像素輸入
        GUILayout.BeginArea(new Rect(150, 30, 150, 100));
        GUILayout.BeginHorizontal();
        spriteSegmentationType = GUILayout.TextField(spriteSegmentationType);
        GUILayout.EndHorizontal();
        GUILayout.EndArea();

        // Sprite標籤
        GUILayout.BeginArea(new Rect(0, 110, 300, 100));
        GUILayout.BeginHorizontal();
        GUILayout.Label(&quot;Sprite 標簽名稱&quot;);
        GUILayout.EndArea();
        GUILayout.EndHorizontal();

        // Sprite標籤輸入
        GUILayout.BeginArea(new Rect(148, 110, 150, 100));
        GUILayout.BeginHorizontal();
        spriteName = GUILayout.TextField(spriteName);
        GUILayout.EndHorizontal();
        GUILayout.EndArea();

        GUILayout.BeginArea(new Rect(200, 150, 100, 100));
        GUILayout.BeginHorizontal();
        if (GUILayout.Button(&quot;確定&quot;))
            SetPivots();
        GUILayout.EndHorizontal();
        GUILayout.EndArea();
    }
 
    // 分割動作
    void SetPivots()
    {
        spriteTitleNumber = 0;
        // 判斷轉型成功執行分割
        if (int.TryParse(spriteSegmentationType, out spriteSegmentationNumber))
        {
            Object[] textures = getSelectTexture();
            Selection.objects = new Object[0];

            SpriteMetaData d = new SpriteMetaData();
            
            foreach (Texture2D texture in textures)
            {
                string path = AssetDatabase.GetAssetPath(texture);
                TextureImporter ti = AssetImporter.GetAtPath(path) as TextureImporter;
                ti.isReadable = true;
                List newData = new List();
                newData.Remove(d);
                for (int x = 0; x &lt; texture.width; x += spriteSegmentationNumber)
                {
                    for (int y = 0; y &lt; texture.height; y += spriteSegmentationNumber)
                    {
                        d.alignment = 9;
                        d.pivot = new Vector2(0.5f, 0.5f);
                        d.name = spriteName + &quot;_&quot; + (spriteTitleNumber += 1);
                        d.rect = new Rect(x, y, spriteSegmentationNumber, spriteSegmentationNumber);
                        newData.Add(d);
                    }
                }
                ti.spritesheet = newData.ToArray();
                AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);
            }
        }
    }
}

 

-------------- 顯示結果圖下

111.PNG

 

 

 

 

 

 

 

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

  • 這是一篇加密文章,請輸入密碼
  • 密碼提示:翔太
  • 請輸入密碼:
  • 這是一篇加密文章,請輸入密碼
  • 密碼提示:愛女孩
  • 請輸入密碼:
  • 這是一篇加密文章,請輸入密碼
  • 密碼提示:女孩
  • 請輸入密碼:

在JAVA 程式註冊 Broadcast Receiver 的寫法 :

XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MyActivity">

<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/EditTxt"
android:textSize="30sp"
android:text=""
/>
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="確定"
android:textSize="30sp"
android:layout_below="@+id/EditTxt"
/>

<TextView
android:id="@+id/txtView"
android:layout_below="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</RelativeLayout>

-----------------------------------------------------

JAVA: MyActivity

 

package com.example.user.test;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class MyActivity extends Activity{

Button btnTest;
EditText editTextTest;
public TextView txtViewTest;
String stringTxt;

TestBroadcaseReceiver testBroadcaseRecTest;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);

(btnTest = (Button)findViewById(R.id.btn1)).setOnClickListener(btnOnClickLinter);
editTextTest = (EditText)findViewById(R.id.EditTxt);
txtViewTest = (TextView)findViewById(R.id.txtView);

stringTxt = editTextTest.getText().toString();

// TestBroadcaseReceiver 註冊
IntentFilter itFile = new IntentFilter(stringTxt);
testBroadcaseRecTest = new TestBroadcaseReceiver();
registerReceiver(testBroadcaseRecTest, itFile);

}
OnClickListener btnOnClickLinter = new OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn1:
test();
}
}
};
public void test() {

//把EditText 的資料指派到strText
String strText = editTextTest.getText().toString();

if(strText.trim().equals("")) {
editTextTest.setError("請輸入訊息");
}else {

//把Intent(stringTxt)數值存職之後判斷"安安"SetText 存直editText直傳給BroadcaseReceiver class
sendBroadcast(new Intent(stringTxt).putExtra("安安", strText));
txtViewTest.setText(stringTxt);
}
}
}

-------------------------------------------------------------

JAVA: TestBroadcaseReceiver

package com.example.user.test;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

/**
* Created by user on 2014/10/30.
*/
public class TestBroadcaseReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {

//intent.getStringExtra("安安") 判斷 putExtra ("安安")取得存值得值
String snder = intent.getStringExtra("安安");
Toast.makeText(context,"收到訊息:"+snder,Toast.LENGTH_SHORT).show();
}
}

------------------------------------------------------

執行結果:

android 執行結果未命名a  

文章標籤

Xauxas 發表在 痞客邦 留言(0) 人氣()

直接用Blender 用方型物件來做動畫。

※ 數字鍵盤: 7 (視圖)。

※ 補充一點: 如果你的預設中心點跑掉的話,請按Shift+c 就會回到中心點了。

Blender

之後開始建立曲線。

步驟:

1. 按下 Shift+a 快捷鍵 。

2. 出現添加視窗選擇曲線。

3. 點下貝茲選項。

 

Blender

 

再來編輯曲線當成物件移動路徑。

步驟:

1. 到編輯模式下(快捷鍵 Tab)。

2. 點貝茲曲線末端中心點按下快捷鍵E來編輯該路徑。

Blender

再來就設定四方形物件的約束。

步驟:

1. 回到物件模式下。

2. 點四方形物件。

3. 在旁邊列選擇物件約束的圖示。

4. 點下添加物體約束下拉式選單。

5. 選擇跟隨路徑屬性選項。

Blender

之後約束設定。

步驟:

1. 選擇路徑的物件名稱。

2. 調整該位置。

3. 跟隨曲線屬性打勾。

Blender

再來設定曲線物件。

1. 點曲線物件。

2. 旁邊列點一下物件資料圖示選項。

3. 再來調整所需的關鍵影格。

4. 在旁邊列會看到路徑動畫的屬性。

Blender  

再來調整路徑動畫屬性。

步驟:

1. 調整所需的關鍵影格。

2. 之後設定所需的評估時間的數值。

3. 在按下快捷鍵I紀錄評估時間數值的關鍵影格(※滑鼠游標一定要在評估時間)

Blender  

再來設定最後一禎的關鍵影格。

 

1. 調整最後一禎的關鍵影格(※關鍵影格一定要先調整,否則會回到第一禎的關鍵影格的數值)。

 

2. 之後設定所需的評估時間的數值。

 

3. 在按下快捷鍵I紀錄評估時間數值的關鍵影格(※滑鼠游標一定要在評估時間)

Blender  

基本的關鍵影格設定完畢之後,就是撥放看看是否結果跟我們所規劃的一樣。

按下Shift+A 可以自動撥放下面的關鍵影格,查看是否路徑規劃一樣。

※ 不一樣的話,四方形物件的約束重新設定。

Blender

  

 

Xauxas 發表在 痞客邦 留言(0) 人氣()

我使用的Blender 2.67 版本,已經支援中文路徑囉。

在講驅動動畫之前,先來看一下傳統動畫與驅動的話的差別:

 

在傳統動畫的做法:

以這四方形跟UV球體來呈現Blender 視窗。

blender 視窗  

如果要用UV球的移動到另外一邊四方形回移動位置不讓UV球體撞到,以傳統動畫的做法是:

大家一定要先知道一件事情,在做動畫之前要先注意關鍵影格的調整Blender 內建 24 fbs

※ 在blender環境裡,每一個物件都可以做動畫,它的優點是: 如果你想要做另外一個物件的動畫的時候,直接點下一個物件之後再來設定動畫,是不會影響另外一個物件動畫的。

建議: 關鍵影格大概動作先以20-30偵來做為分別,不建議低於20偵以下

步驟:

1. 先點選你要移動的物件。

2. 再點選關鍵影格偵。

3. 案I選擇位置。(因為我只讓UV球體往前而已,所以選擇位置 ※ 如果物件動作不一樣,就選擇應當的項目)

※ 一定要先移動關鍵影格偵之後再來設定。

傳統動畫設定。

 

之後移動移動物件之後再設定,步驟如同一樣。

※ 我們可以拉動下面的關鍵影格偵,來試試看是否成功讓物件有所動作。

傳統動畫完成圖

 

 

影片觀看網址(裡面包含以上操作):https://www.youtube.com/watch?v=YlmLsh3LWIQ

---------------------------------------------------------------------------------------------------------------------------

做驅動之前要先知道,每一個物件旁編列的功能去控制物件旁編列的功能數據,簡單說: 物件功能去控制另外一個物件功能產生動畫。

驅動方法製作動畫:

以這四方形跟UV球體來呈現Blender 視窗。

 blender 視窗

如果要用UV球的移動到另外一邊四方形回移動位置不讓UV球體撞到,以驅動製作成動畫的做法是:

※ UV球體過去,四方體移到旁邊去,表示說: UV 球體是以座標y軸移動,在撞到之前四方體以座標x軸移動,所先要有這個觀念。

步驟: 

1: 點選四方形物件

2. 在旁編列按下X軸座標選擇單一驅動器(物體)。

物件驅動器設  

再來步驟:

1. 請到圖表編輯器之後選擇驅動器。

2. 之後點選X軸座標。

在旁編列(如果沒出現旁編列請按 快捷鍵: n):

3. 表述視窗列一定要打上下面的變數名稱(變數名稱一定都要一樣)。

4. 請選擇以下你要控制的物件名稱。

5. 在選擇你要的控制方向。

※ 之後會發現到四方形物件移位了,再來你可以用UV球體以你設定的座標移動看看,四方形是會動的。

※ 如果沒有動作請重新設定。

驅動的圖表編輯器操作

但是...你會發現到....你的四方形一開始的位置跟你想的位置不同...所以我們還要再做設定。

步驟:

1. 你會先看到圖表編輯器本身的是內建的。

2. 旁編列有一個修改器,請按旁邊的X按鈕。

刪除內建圖表  

之後還要做一個動作...四方形才能歸位。

步驟(一定要先案Ctrl+左鍵繪製):

1. 先移動UV球體移動,看設計者想要在哪個座標讓四方體移動。

2.之後把UV求體移動座標打上四方形的驅動視窗裡。

3. 之後按一下更新相依關西,四方形就能歸位。

※ 在線圖裡面橫向是X軸,縱向是Y軸。

讓有驅動的物件歸位  

之後就可以控制移動四方形做法:

步驟:

※ 跟上面步驟差不多,但是還是提醒先要繪製點,之後調整座標。

設定完之後,四方形就能移動了。

物件移動座標設定

 

之後再把UV球體設定關鍵影格(傳統動畫是步驟一樣的),就能完成動畫囉。

影片觀看網址(裡面包含以上操作):https://www.youtube.com/watch?v=EG40JoSz-SE

 

-------------------------------------------------------------------------------------------------------------------

傳統動畫跟驅動動畫比較(我這邊直接做影片...直接用看來體會會更清楚):

假設我們改一下座標:

傳統做法影片: https://www.youtube.com/watch?v=xc3yNKNoles

相當明顯的....如果傳統做法的話,只要一個物件改變了座標,另一個物件的座標都要依依改變,是相當麻煩的。

表示說: 每一次座標移動,都要去設定關鍵影格偵。

驅動做法影片: http://www.youtube.com/watch?v=bwC_TtVtg0I

相當明顯的....如果驅動做法的話,只要一個物件改變了座標,另一個物件的座標都不會被影響。

表示說: 驅動做法是直接設定綁定座標。

 

 

 

Xauxas 發表在 痞客邦 留言(2) 人氣()