반응형

string.format() 은 다양한 포맷형태를 변환하여 문자열을 나타내 주는데요 

만약 아래와같이 수식 문자열은 어덯게 처리해야할까요 ? 

 

string TestExpression = "(A-B)*C";

 

 

string.format으로는 활용하기엔 힘드는것처럼 보입니다. 

DataTable 클래스를 활용하면 된다고 하기 한번 테스트 해보앗습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void Start()
    {   
        //예시수식
        string TestExpression = "(A-B)*C";
 
        //Table 생성
        DataTable table = new DataTable();
 
        //table에 해당 열을 생성
        table.Columns.Add("A"typeof(int));
        table.Columns.Add("B"typeof(int));
        table.Columns.Add("C"typeof(int));
        table.Columns.Add("Result"typeof(int));
 
        //Result 열에 수식을 입력
        table.Columns["Result"].Expression = TestExpression;
 
        //해당 열의 행에 값을입력
        DataRow row = table.Rows.Add();
        row["A"= 31;
        row["B"= 5;
        row["C"= 1;
 
        //테이블 로드하고 로드끝내기
        table.BeginLoadData();
        table.EndLoadData();
 
        //Result 열의 행값을 
        int a = (int)row["Result"];
 
        Debug.Log(a);
        //출력값 : 26
       
 
    }
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

위코드를 엑셀로 표식화 해보앗습니다

 

 

 

TableData로 이용하니 해당수식을 잘 계산되서 나오네요 

 

이제 이걸 잘 함수화 시키면되겟네요 

 

 

 

 

반응형
반응형

안드로이드가 점점 보안에대해 강화시키고 있는거 같네요 

 

안드로이드 보안 강화 관련 -> https://android-developers.googleblog.com/2018/04/protecting-users-with-tls-by-default-in.html

 


안드로이드는 마시멜로우부터 우발적 인 암호화되지 않은 연결을 방지하기 위해 노력해왔는데요

pie 버전에서 네트워크보안을 강화하여 http 주소인 웹주소 사용못하고 https로 사용강제하도록 한다네요 

 

이러므로 웹서버와 http로 송신할때 송신이 되지않는경우가 Pie버전에 발견되어서 대처를 햇습니다.

 

 

- 대처 방법

 

menifest 에 아래 처럼 android:usesCleartextTraffic="true" 태그를 추가합니다

 


  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="패키지이름" xmlns:tools="http://schemas.android.com/tools" android:installLocation="auto">
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
  <application 
    android:usesCleartextTraffic="true"
    android:theme="@style/UnityThemeSelector" 
    android:icon="@mipmap/app_icon" 
    android:label="@string/app_name" 
    android:isGame="true" 
    android:banner="@drawable/app_banner">
    <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
      </intent-filter>
      <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
  </application>
</manifest>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs

 

 

 

 

- 다른 대처 방법 

 

아래 링크에 다른대처방법도 잇으니 확인해 보세요 
      
https://gun0912.tistory.com/80
    
  

 

 

 

반응형
반응형

 

 - 해당오브젝트 인스펙터에 버튼을 만들기 입니다.

   1. 에디터 스크립트 만들기
   2. 에디터 스크립트에 Editor 상속하고 오버라이드 함수 활용하기 
   3. 인스펙터에 보일 스크립트 만들기 

 

 

 

 

 

   1. 에디터 스크립트 만들기

 

프로젝트 폴더 아무곳에 ItemEffectTriggerEditor .cs 와같이 c# 스크립트를 만듭니다.

경로는 아무상관없습니다.

 

 

  2. 에디터 스크립트에 Editor 상속하고 오버라이드 함수 활용하기 

using UnityEditor;  //Editor 클래스 사용하기 위해 넣어줍니다.
using UnityEngine;

 

 

 

// 오브젝트 인스펙터에 활용하는 클래스 이름을 넣습니다 . ex) [CustomEditor(typeof(오브젝트넣을 스크립트 클래스))] 

[CustomEditor(typeof(ItemEffectTrigger))] 
public class ItemEffectTriggerEditor : Editor //Monobehaviour 대신 Editor를 넣습니다.
{
    

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

 

       //ItemEffectTrigger.cs 의 객체를 받아옵니다 => 이래야 버튼시 명령을 내릴수 잇습니다
        ItemEffectTrigger itemtrigger = (ItemEffectTrigger)target;

        EditorGUILayout.BeginHorizontal();  //BeginHorizontal() 이후 부터는 GUI 들이 가로로 생성됩니다.
        GUILayout.FlexibleSpace(); // 고정된 여백을 넣습니다. ( 버튼이 가운데 오기 위함)
        //버튼을 만듭니다 . GUILayout.Button("버튼이름" , 가로크기, 세로크기)

       if (GUILayout.Button("이펙트 실행", GUILayout.Width(120), GUILayout.Height(30))) 
        {

           //ItemEffectTrigger 클래스에서 버튼 누를시 해당 명령을 구현해줍니다.
            itemtrigger.Start_ItemEffect();
        }
        GUILayout.FlexibleSpace();  // 고정된 여백을 넣습니다.
        EditorGUILayout.EndHorizontal();  // 가로 생성 끝

    }
}

 

 

  3. 인스펙터에 보일 스크립트 만들기 

public class ItemEffectTrigger : MonoBehaviour
{
 


    public void Start_ItemEffect()
    {
        //구현내용
    }

 

}

 

 

 

 

 

-결과-

 

반응형
반응형

 

방법 1.

// 가로 , 세로 값 지정해서 Resize하기
    private Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
    {
        Texture2D result = new Texture2D(targetWidth, targetHeight, source.format, true);
        Color[] rpixels = result.GetPixels(0);
        float incX = (1.0f / (float)targetWidth);
        float incY = (1.0f / (float)targetHeight);
        for (int px = 0; px < rpixels.Length; px++)
        {
            rpixels[px] = source.GetPixelBilinear(incX * ((float)px % targetWidth), incY * ((float)Mathf.Floor(px / targetWidth)));
        }
        result.SetPixels(rpixels, 0);
        result.Apply();
        return result;
    }

 

 

 

 

 

 

방법 2.
    // 비율로 해서 Resize하기
    public  Texture2D ScaleTexture( Texture2D source, float _scaleFactor)
    {
        if (_scaleFactor == 1f)
        {
            return source;
        }
        else if (_scaleFactor == 0f)
        {
            return Texture2D.blackTexture;
        }

        int _newWidth = Mathf.RoundToInt(source.width * _scaleFactor);
        int _newHeight = Mathf.RoundToInt(source.height * _scaleFactor);


        
        Color[] _scaledTexPixels = new Color[_newWidth * _newHeight];

        for (int _yCord = 0; _yCord < _newHeight; _yCord++)
        {
            float _vCord = _yCord / (_newHeight * 1f);
            int _scanLineIndex = _yCord * _newWidth;

            for (int _xCord = 0; _xCord < _newWidth; _xCord++)
            {
                float _uCord = _xCord / (_newWidth * 1f);

                _scaledTexPixels[_scanLineIndex + _xCord] = source.GetPixelBilinear(_uCord, _vCord);
            }
        }

        // Create Scaled Texture
        Texture2D result = new Texture2D(_newWidth, _newHeight, source.format, false);
        result.SetPixels(_scaledTexPixels, 0);
        result.Apply();

        return result;
    }

반응형
반응형

1. 소숫자리수 표현

 string.Format("{0:f2}%",23.44555);

결과 => 23.44%

 

string.Format("{0:00}%",23.44555);

결과 => 23%

 

2.숫자 1000 단위 마다 콤마(,) 추가하기

int cnt = 45646

string str string.Format("{0:#,###}", cnt));

 

 결과 => 45,646

 

 

3. 0000 채워 넣기

string str = string.Format("{0:D4}", 22);

결과 => 0022

 

 


4. 백분율로 나타내기

string.Format("{0:P}", 0.2189);

결과 => 21.89%

string.Format("{0:P1}", 0.2189);

결과 => 21.8%

반응형
반응형

* 간단 요약

카메라 두대로 culling mask 이용하여 자연스러운 흔들기 연출 하겟습니다.

카메라 두대중 mainCamera 는 플레이어만 보이게하고,

subCamera 는 플레이어 제외하고 모든 오브젝트 보이게 합니다.

그리고 총쏠때(흔들 시점에) subCamera를 x,y 축위치를 랜덤으로 변경하여 흔들기를 해줍니다.

 

 

 

 

 

- 두카메라를 부모오브젝트에 상속

    CamAxis

     └ Main Camera

     └ Sub Camera

 

 

- 메인 카메라에 플레이어만 Culling mask 지정 

  Clear flags 는 Skybox로 

 

 

 

 

 

-서브 카메라는 Player 제외하고 모든 레이어 지정

 

 

 

 

- 플레이어 오브젝트에 레이어 지정 (플레이어 의 하부 오브젝트까지 지정해줍니다 )

 

 

 

 

 

 

-메인카메라로 확인하시면 플레이어만 보이는것을 확인할수 잇다.

 

 

 

 

- 서브카메라 보면 플레이어 제외하고 모든 오브젝트를 보이는것이 확인이 된다.

 

 

 

- 두카메라가 다같이 표현되어 플레이어와 모든 오브젝트가 보이는것을 확인 할수잇다.

 

 

 

 

 

 

 

 

 

- 이제 총을쏠때 흔들기를 하자

  카메라 부모오브젝트 (CamAxis) 에 아래 스크립트를 넣자

 

  기본적으로 CamAxis 는 Player스크립트에서 Update로  마우스 위치값을 받아 상하좌우 움직임을 하고 잇다.

이 상태에서 총쏠때  마다 Set_Shaking(일정수치) 호출해준다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//마우스 움직임 따라 메인캠 부모 Trasform이 움직인다 =>Player.cs Update() 함수에서 호출 된다
 public void FollowCamToTarget(Vector3 targetPosition)
  {
        //메인캠의 부모Tr pos는 마우스 포인터따라 움직인다
        CameraAxis.localPosition = targetPosition;
        CamOrinPos = targetPosition;
 
        //서브캠이 흔들린다
        SubCameraTransform.localPosition = ShakeVector;
  }
 
 
    Vector3 ShakeVector = new Vector3();
    float ShakeCameraForce = 0f;
    float ShakeCameraSpeed = 0f;
    Vector3 CamOrinPos = Vector3.zero;
    public void Set_Shaking(float shakeForce) //총 한번 쏠때마다 이 함수가 호출된다
    {
 
        // 흔들림 값 할당
        ShakeCameraForce = shakeForce;
        //흔들림 속도 할당
        ShakeCameraSpeed = ShakeCameraForce / 2;
        // 흔들기 시작
        StartCoroutine(Co_Shake());
    }
 
   
   
    //카메라 흔들기 동작
    IEnumerator Co_Shake()
    {
        while(ShakeCameraForce > 0f)
        {
            float shaking = 0.04f * ShakeCameraForce;
 
// x, y 축 움직일 랜덤값
            float xrand = Random.Range(-shaking, shaking);
            float yrand = Random.Range(0, shaking);
            ShakeVector = new Vector3(xrand, yrand, 0);
 
 
            ShakeCameraForce -= Time.deltaTime * 10f * ShakeCameraSpeed;
            
            yield return null;
        }
 
        //동작 완료후 제자리로 
        ShakeVector = Vector3.zero;
       // 서브캠 제자리로 
        SubCameraTransform.localPosition = ShakeVector;
    }
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4f; text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none; color:white">cs
 
 
 

 

 

 

 

 

 

* 카메라 두대로 사용하여 아래 첫 움짤 처럼 보이게 된다. 

 

* 카메라 한대로 사용하여 두번쨰 움짤을 보게 되면, 플레이어만 흔들리는 것처럼 보일것이다.

  이런 이유로 두대로 CullingMask를 사용하여 플레이어는 흔들리것이 보이지 않게 연출 한것이다.

 

 

* 각 카메라가 중첩되지 않은 Layer를 선택해서 렌더링 시키고 있기때문에 Batch, SetPassCall 에는 커지는 영향이 없다.카메라 한대쓰는것이랑 같다.

 

 

 

 

 

 #카메라 두대 사용하여 연출햇을떄

 

 

 

 

 

 

# 카메라한대로 카메라 흔들기 했을때

 

 

반응형
반응형

 

사용 방법입니다.

 

우선 각 enum에 의미는

 

 RigidbodyConstraints.FreezeRotationX  //X회전 프리즌(회전하지않기)

RigidbodyConstraints.FreezeRotationY  //Y회전 프리즌(회전하지않기)

RigidbodyConstraints.FreezeRotationZ //Z회전 프리즌

RigidbodyConstraints.FreezePositionX //X위치 프리즌 (X축이동 하지않기)

RigidbodyConstraints.FreezePositionY //Y위치 프리즌 (Y축이동 하지않기)

RigidbodyConstraints.FreezePositionZ //Z위치 프리즌 (Z축이동 하지않기)

 

 

 

코드로 제어 하실때는 

 

  rigid.constraints = RigidbodyConstraints.FreezeRotationX ; 

만약 여러게 제어를 넣고 싶으면 

  rigid.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY ;

 

 

 

아래 예제입니다.


            if (rigid == null)
            {
                //리지바디 추가
                rigid = tr.gameObject.AddComponent();
                rigid.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY |
                    RigidbodyConstraints.FreezeRotationZ | RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ;
            }

반응형
반응형

NavMeshAgent.SetDestination 호출후 같은 프레임에 네비는 바로 적용이 되지 않습니다.

 

SetDestination 호출후 목적지 계산이 필요하므로  네비 계산이 완료 되면 다음 프레임에 목적지 이동 하기 시작합니다.

 

 

위와 같은 확인은 같은 프레임에서 NavMeshAgent.SetDestination 호출후 NavMeshAgent.remainDistance를 확인해 보면 값이 0 인걸 알수 잇습니다.

 

다음 프레임 쯔음에 다시 NavMeshAgent.remainDistance 확인해 보면 목적지까지의 현재 거리를 나타납니다 ,

이떄 네비가 계산완료하여 움직입니다.

 

 

그래서 NavMeshAgent.SetDestination 호출후 바로 네비가 적용되지 않으니

네비가 계산완료 할떄까지 기달려야합니다. 

 

NavMeshAgent 는 계산이 완료 되엇다는  프로퍼티를 제공하니 (NavMeshAgent.pathPending) 활용하면 좋을거 같습니다 .

 

유니티 레퍼런스에 의하면 NavMeshAgent.pathPending 는

"계산중이지만 아직 준비가 되지 않는 경로(path)를 나타냅니다." 라고 설명되어있습니다.

그래서 pathPending  가 false 이면 계산완료 햇다는 것입니다.

 

 

 

ex) NavMeshAgent.pathPending 사용 예 

void Update()

{

   if(!NavMeshAgent.pathPending)

   {

      //계산 완료하였으니 이제 목적지까지 이동하기 시작한다.

   }

}

반응형

+ Recent posts